diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2015-06-15 03:00:00 +0300 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:16:54 +0300 |
commit | 54490d51d5c6b0d794dcbad2d634d4c95fc25b6c (patch) | |
tree | c3c413656432c0ef87b2841c80e42b55ad17d4e8 /CPP/7zip/Compress | |
parent | 0713a3ab803e57401f18432148b4139e5fe6e5dd (diff) |
15.0515.05
Diffstat (limited to 'CPP/7zip/Compress')
63 files changed, 1714 insertions, 2085 deletions
diff --git a/CPP/7zip/Compress/ArjDecoder1.cpp b/CPP/7zip/Compress/ArjDecoder1.cpp deleted file mode 100644 index 2eaa591c..00000000 --- a/CPP/7zip/Compress/ArjDecoder1.cpp +++ /dev/null @@ -1,309 +0,0 @@ -// ArjDecoder1.cpp - -#include "StdAfx.h" - -#include "ArjDecoder1.h" - -namespace NCompress{ -namespace NArj { -namespace NDecoder1 { - -static const UInt32 kHistorySize = 26624; -static const UInt32 kMatchMinLen = 3; -static const UInt32 kMatchMaxLen = 256; - -// static const UInt32 kNC = 255 + kMatchMaxLen + 2 - kMatchMinLen; - -void CCoder::MakeTable(int nchar, Byte *bitlen, int tablebits, - UInt32 *table, int tablesize) -{ - UInt32 count[17], weight[17], start[18], *p; - UInt32 i, k, len, ch, jutbits, avail, nextcode, mask; - - for (i = 1; i <= 16; i++) - count[i] = 0; - for (i = 0; (int)i < nchar; i++) - count[bitlen[i]]++; - - start[1] = 0; - for (i = 1; i <= 16; i++) - start[i + 1] = start[i] + (count[i] << (16 - i)); - if (start[17] != (UInt32) (1 << 16)) - throw "Data error"; - - jutbits = 16 - tablebits; - for (i = 1; (int)i <= tablebits; i++) - { - start[i] >>= jutbits; - weight[i] = 1 << (tablebits - i); - } - while (i <= 16) - { - weight[i] = 1 << (16 - i); - i++; - } - - i = start[tablebits + 1] >> jutbits; - if (i != (UInt32) (1 << 16)) - { - k = 1 << tablebits; - while (i != k) - table[i++] = 0; - } - - avail = nchar; - mask = 1 << (15 - tablebits); - for (ch = 0; (int)ch < nchar; ch++) - { - if ((len = bitlen[ch]) == 0) - continue; - k = start[len]; - nextcode = k + weight[len]; - if ((int)len <= tablebits) - { - if (nextcode > (UInt32)tablesize) - throw "Data error"; - for (i = start[len]; i < nextcode; i++) - table[i] = ch; - } - else - { - p = &table[k >> jutbits]; - i = len - tablebits; - while (i != 0) - { - if (*p == 0) - { - right[avail] = left[avail] = 0; - *p = avail++; - } - if (k & mask) - p = &right[*p]; - else - p = &left[*p]; - k <<= 1; - i--; - } - *p = ch; - } - start[len] = nextcode; - } -} - -void CCoder::read_pt_len(int nn, int nbit, int i_special) -{ - UInt32 n = m_InBitStream.ReadBits(nbit); - if (n == 0) - { - UInt32 c = m_InBitStream.ReadBits(nbit); - int i; - for (i = 0; i < nn; i++) - pt_len[i] = 0; - for (i = 0; i < 256; i++) - pt_table[i] = c; - } - else - { - UInt32 i = 0; - while (i < n) - { - UInt32 bitBuf = m_InBitStream.GetValue(16); - int c = bitBuf >> 13; - if (c == 7) - { - UInt32 mask = 1 << (12); - while (mask & bitBuf) - { - mask >>= 1; - c++; - } - } - m_InBitStream.MovePos((c < 7) ? 3 : (int)(c - 3)); - pt_len[i++] = (Byte)c; - if (i == (UInt32)i_special) - { - c = m_InBitStream.ReadBits(2); - while (--c >= 0) - pt_len[i++] = 0; - } - } - while (i < (UInt32)nn) - pt_len[i++] = 0; - MakeTable(nn, pt_len, 8, pt_table, PTABLESIZE); - } -} - -void CCoder::read_c_len() -{ - int i, c, n; - UInt32 mask; - - n = m_InBitStream.ReadBits(CBIT); - if (n == 0) - { - c = m_InBitStream.ReadBits(CBIT); - for (i = 0; i < NC; i++) - c_len[i] = 0; - for (i = 0; i < CTABLESIZE; i++) - c_table[i] = c; - } - else - { - i = 0; - while (i < n) - { - UInt32 bitBuf = m_InBitStream.GetValue(16); - c = pt_table[bitBuf >> (8)]; - if (c >= NT) - { - mask = 1 << (7); - do - { - if (bitBuf & mask) - c = right[c]; - else - c = left[c]; - mask >>= 1; - } while (c >= NT); - } - m_InBitStream.MovePos((int)(pt_len[c])); - if (c <= 2) - { - if (c == 0) - c = 1; - else if (c == 1) - c = m_InBitStream.ReadBits(4) + 3; - else - c = m_InBitStream.ReadBits(CBIT) + 20; - while (--c >= 0) - c_len[i++] = 0; - } - else - c_len[i++] = (Byte)(c - 2); - } - while (i < NC) - c_len[i++] = 0; - MakeTable(NC, c_len, 12, c_table, CTABLESIZE); - } -} - -UInt32 CCoder::decode_c() -{ - UInt32 j, mask; - UInt32 bitbuf = m_InBitStream.GetValue(16); - j = c_table[bitbuf >> 4]; - if (j >= NC) - { - mask = 1 << (3); - do - { - if (bitbuf & mask) - j = right[j]; - else - j = left[j]; - mask >>= 1; - } while (j >= NC); - } - m_InBitStream.MovePos((int)(c_len[j])); - return j; -} - -UInt32 CCoder::decode_p() -{ - UInt32 j, mask; - UInt32 bitbuf = m_InBitStream.GetValue(16); - j = pt_table[bitbuf >> (8)]; - if (j >= NP) - { - mask = 1 << (7); - do - { - if (bitbuf & mask) - j = right[j]; - else - j = left[j]; - mask >>= 1; - } while (j >= NP); - } - m_InBitStream.MovePos((int)(pt_len[j])); - if (j != 0) - { - j--; - j = (1 << j) + m_InBitStream.ReadBits((int)j); - } - return j; -} - - -HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - if (outSize == NULL) - return E_INVALIDARG; - - if (!m_OutWindowStream.Create(kHistorySize)) - return E_OUTOFMEMORY; - if (!m_InBitStream.Create(1 << 20)) - return E_OUTOFMEMORY; - - // check it - for (int i = 0; i < CTABLESIZE; i++) - c_table[i] = 0; - - UInt64 pos = 0; - m_OutWindowStream.SetStream(outStream); - m_OutWindowStream.Init(false); - m_InBitStream.SetStream(inStream); - m_InBitStream.Init(); - - CCoderReleaser coderReleaser(this); - - UInt32 blockSize = 0; - - while (pos < *outSize) - { - if (blockSize == 0) - { - if (progress != NULL) - { - UInt64 packSize = m_InBitStream.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&packSize, &pos)); - } - blockSize = m_InBitStream.ReadBits(16); - read_pt_len(NT, TBIT, 3); - read_c_len(); - read_pt_len(NP, PBIT, -1); - } - blockSize--; - - UInt32 number = decode_c(); - if (number < 256) - { - m_OutWindowStream.PutByte((Byte)number); - pos++; - continue; - } - else - { - UInt32 len = number - 256 + kMatchMinLen; - UInt32 distance = decode_p(); - if (distance >= pos) - return S_FALSE; - m_OutWindowStream.CopyBlock(distance, len); - pos += len; - } - } - coderReleaser.NeedFlush = false; - return m_OutWindowStream.Flush(); -} - -STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - try { return CodeReal(inStream, outStream, inSize, outSize, progress);} - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(const CLzOutWindowException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } -} - -}}} diff --git a/CPP/7zip/Compress/ArjDecoder1.h b/CPP/7zip/Compress/ArjDecoder1.h deleted file mode 100644 index dd12e445..00000000 --- a/CPP/7zip/Compress/ArjDecoder1.h +++ /dev/null @@ -1,91 +0,0 @@ -// ArjDecoder1.h - -#ifndef __COMPRESS_ARJ_DECODER1_H -#define __COMPRESS_ARJ_DECODER1_H - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -#include "../Common/InBuffer.h" - -#include "BitmDecoder.h" -#include "LzOutWindow.h" - -namespace NCompress { -namespace NArj { -namespace NDecoder1 { - -#define CODE_BIT 16 - -#define THRESHOLD 3 -#define DDICSIZ 26624 -#define MAXDICBIT 16 -#define MATCHBIT 8 -#define MAXMATCH 256 -#define NC (0xFF + MAXMATCH + 2 - THRESHOLD) -#define NP (MAXDICBIT + 1) -#define CBIT 9 -#define NT (CODE_BIT + 3) -#define PBIT 5 -#define TBIT 5 - -#if NT > NP -#define NPT NT -#else -#define NPT NP -#endif - -#define CTABLESIZE 4096 -#define PTABLESIZE 256 - - -class CCoder : - public ICompressCoder, - public CMyUnknownImp -{ - CLzOutWindow m_OutWindowStream; - NBitm::CDecoder<CInBuffer> m_InBitStream; - - UInt32 left[2 * NC - 1]; - UInt32 right[2 * NC - 1]; - Byte c_len[NC]; - Byte pt_len[NPT]; - - UInt32 c_table[CTABLESIZE]; - UInt32 pt_table[PTABLESIZE]; - - class CCoderReleaser - { - CCoder *m_Coder; - public: - bool NeedFlush; - CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {} - ~CCoderReleaser() - { - if (NeedFlush) - m_Coder->m_OutWindowStream.Flush(); - } - }; - friend class CCoderReleaser; - - void MakeTable(int nchar, Byte *bitlen, int tablebits, UInt32 *table, int tablesize); - - void read_c_len(); - void read_pt_len(int nn, int nbit, int i_special); - UInt32 decode_c(); - UInt32 decode_p(); - - HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); -public: - MY_UNKNOWN_IMP - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - -}; - -}}} - -#endif diff --git a/CPP/7zip/Compress/ArjDecoder2.cpp b/CPP/7zip/Compress/ArjDecoder2.cpp deleted file mode 100644 index 4903605c..00000000 --- a/CPP/7zip/Compress/ArjDecoder2.cpp +++ /dev/null @@ -1,91 +0,0 @@ -// ArjDecoder2.cpp - -#include "StdAfx.h" - -#include "ArjDecoder2.h" - -namespace NCompress{ -namespace NArj { -namespace NDecoder2 { - -static const UInt32 kHistorySize = 26624; -static const UInt32 kMatchMinLen = 3; - -HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo * /* progress */) -{ - if (outSize == NULL) - return E_INVALIDARG; - - if (!m_OutWindowStream.Create(kHistorySize)) - return E_OUTOFMEMORY; - if (!m_InBitStream.Create(1 << 20)) - return E_OUTOFMEMORY; - - UInt64 pos = 0; - m_OutWindowStream.SetStream(outStream); - m_OutWindowStream.Init(false); - m_InBitStream.SetStream(inStream); - m_InBitStream.Init(); - - CCoderReleaser coderReleaser(this); - - while (pos < *outSize) - { - const UInt32 kStartWidth = 0; - const UInt32 kStopWidth = 7; - UInt32 power = 1 << kStartWidth; - UInt32 width; - UInt32 len = 0; - for (width = kStartWidth; width < kStopWidth; width++) - { - if (m_InBitStream.ReadBits(1) == 0) - break; - len += power; - power <<= 1; - } - if (width != 0) - len += m_InBitStream.ReadBits(width); - if (len == 0) - { - m_OutWindowStream.PutByte((Byte)m_InBitStream.ReadBits(8)); - pos++; - continue; - } - else - { - len = len - 1 + kMatchMinLen; - const UInt32 kStartWidth = 9; - const UInt32 kStopWidth = 13; - UInt32 power = 1 << kStartWidth; - UInt32 width; - UInt32 distance = 0; - for (width = kStartWidth; width < kStopWidth; width++) - { - if (m_InBitStream.ReadBits(1) == 0) - break; - distance += power; - power <<= 1; - } - if (width != 0) - distance += m_InBitStream.ReadBits(width); - if (distance >= pos) - return S_FALSE; - m_OutWindowStream.CopyBlock(distance, len); - pos += len; - } - } - coderReleaser.NeedFlush = false; - return m_OutWindowStream.Flush(); -} - -STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - try { return CodeReal(inStream, outStream, inSize, outSize, progress);} - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(const CLzOutWindowException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } -} - -}}} diff --git a/CPP/7zip/Compress/ArjDecoder2.h b/CPP/7zip/Compress/ArjDecoder2.h deleted file mode 100644 index cf544d9e..00000000 --- a/CPP/7zip/Compress/ArjDecoder2.h +++ /dev/null @@ -1,52 +0,0 @@ -// ArjDecoder2.h - -#ifndef __COMPRESS_ARJ_DECODER2_H -#define __COMPRESS_ARJ_DECODER2_H - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -#include "../Common/InBuffer.h" - -#include "BitmDecoder.h" -#include "LzOutWindow.h" - -namespace NCompress { -namespace NArj { -namespace NDecoder2 { - -class CCoder : - public ICompressCoder, - public CMyUnknownImp -{ - CLzOutWindow m_OutWindowStream; - NBitm::CDecoder<CInBuffer> m_InBitStream; - - class CCoderReleaser - { - CCoder *m_Coder; - public: - bool NeedFlush; - CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {} - ~CCoderReleaser() - { - if (NeedFlush) - m_Coder->m_OutWindowStream.Flush(); - } - }; - friend class CCoderReleaser; - - HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); -public: - MY_UNKNOWN_IMP - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - -}; - -}}} - -#endif diff --git a/CPP/7zip/Compress/BZip2Const.h b/CPP/7zip/Compress/BZip2Const.h index 62427aa6..588f5ae0 100644 --- a/CPP/7zip/Compress/BZip2Const.h +++ b/CPP/7zip/Compress/BZip2Const.h @@ -25,29 +25,30 @@ const Byte kBlockSig3 = 0x26; const Byte kBlockSig4 = 0x53; const Byte kBlockSig5 = 0x59; -const int kNumOrigBits = 24; +const unsigned kNumOrigBits = 24; -const int kNumTablesBits = 3; -const int kNumTablesMin = 2; -const int kNumTablesMax = 6; +const unsigned kNumTablesBits = 3; +const unsigned kNumTablesMin = 2; +const unsigned kNumTablesMax = 6; -const int kNumLevelsBits = 5; +const unsigned kNumLevelsBits = 5; -const int kMaxHuffmanLen = 20; // Check it +const unsigned kMaxHuffmanLen = 20; // Check it -const int kMaxAlphaSize = 258; +const unsigned kMaxAlphaSize = 258; -const int kGroupSize = 50; +const unsigned kGroupSize = 50; + +const unsigned kBlockSizeMultMin = 1; +const unsigned kBlockSizeMultMax = 9; -const int kBlockSizeMultMin = 1; -const int kBlockSizeMultMax = 9; const UInt32 kBlockSizeStep = 100000; const UInt32 kBlockSizeMax = kBlockSizeMultMax * kBlockSizeStep; -const int kNumSelectorsBits = 15; +const unsigned kNumSelectorsBits = 15; const UInt32 kNumSelectorsMax = (2 + (kBlockSizeMax / kGroupSize)); -const int kRleModeRepSize = 4; +const unsigned kRleModeRepSize = 4; }} diff --git a/CPP/7zip/Compress/BZip2Decoder.cpp b/CPP/7zip/Compress/BZip2Decoder.cpp index 3798421e..db4d0933 100644 --- a/CPP/7zip/Compress/BZip2Decoder.cpp +++ b/CPP/7zip/Compress/BZip2Decoder.cpp @@ -105,10 +105,10 @@ HRESULT CBase::ReadBlock(UInt32 *charCounters, UInt32 blockSizeMax, CBlockProps CMtf8Decoder mtf; mtf.StartInit(); - int numInUse = 0; + unsigned numInUse = 0; { Byte inUse16[16]; - int i; + unsigned i; for (i = 0; i < 16; i++) inUse16[i] = (Byte)ReadBit(); for (i = 0; i < 256; i++) @@ -121,9 +121,9 @@ HRESULT CBase::ReadBlock(UInt32 *charCounters, UInt32 blockSizeMax, CBlockProps return S_FALSE; // mtf.Init(numInUse); } - int alphaSize = numInUse + 2; + unsigned alphaSize = numInUse + 2; - int numTables = ReadBits(kNumTablesBits); + unsigned numTables = ReadBits(kNumTablesBits); if (numTables < kNumTablesMin || numTables > kNumTablesMax) return S_FALSE; @@ -133,14 +133,14 @@ HRESULT CBase::ReadBlock(UInt32 *charCounters, UInt32 blockSizeMax, CBlockProps { Byte mtfPos[kNumTablesMax]; - int t = 0; + unsigned t = 0; do mtfPos[t] = (Byte)t; while (++t < numTables); UInt32 i = 0; do { - int j = 0; + unsigned j = 0; while (ReadBit()) if (++j >= numTables) return S_FALSE; @@ -152,12 +152,12 @@ HRESULT CBase::ReadBlock(UInt32 *charCounters, UInt32 blockSizeMax, CBlockProps while (++i < numSelectors); } - int t = 0; + unsigned t = 0; do { Byte lens[kMaxAlphaSize]; - int len = (int)ReadBits(kNumLevelsBits); - int i; + unsigned len = (unsigned)ReadBits(kNumLevelsBits); + unsigned i; for (i = 0; i < alphaSize; i++) { for (;;) @@ -166,7 +166,8 @@ HRESULT CBase::ReadBlock(UInt32 *charCounters, UInt32 blockSizeMax, CBlockProps return S_FALSE; if (!ReadBit()) break; - len += 1 - (int)(ReadBit() << 1); + len++; + len -= (ReadBit() << 1); } lens[i] = (Byte)len; } @@ -178,7 +179,7 @@ HRESULT CBase::ReadBlock(UInt32 *charCounters, UInt32 blockSizeMax, CBlockProps while (++t < numTables); { - for (int i = 0; i < 256; i++) + for (unsigned i = 0; i < 256; i++) charCounters[i] = 0; } @@ -187,7 +188,7 @@ HRESULT CBase::ReadBlock(UInt32 *charCounters, UInt32 blockSizeMax, CBlockProps UInt32 groupIndex = 0; UInt32 groupSize = 0; CHuffmanDecoder *huffmanDecoder = 0; - int runPower = 0; + unsigned runPower = 0; UInt32 runCounter = 0; for (;;) @@ -224,7 +225,7 @@ HRESULT CBase::ReadBlock(UInt32 *charCounters, UInt32 blockSizeMax, CBlockProps } if (nextSym <= (UInt32)numInUse) { - UInt32 b = (UInt32)mtf.GetAndMove((int)nextSym - 1); + UInt32 b = (UInt32)mtf.GetAndMove((unsigned)nextSym - 1); if (blockSize >= blockSizeMax) return S_FALSE; charCounters[b]++; @@ -510,7 +511,7 @@ HRESULT CDecoder::ReadSignature(UInt32 &crc) crc = 0; Byte s[10]; - int i; + unsigned i; for (i = 0; i < 10; i++) s[i] = ReadByte(); @@ -576,7 +577,7 @@ HRESULT CDecoder::DecodeFile(ICompressProgressInfo *progress) */ Byte s[4]; - int i; + unsigned i; for (i = 0; i < 4; i++) s[i] = ReadByte(); if (Base.BitDecoder.ExtraBitsWereRead()) diff --git a/CPP/7zip/Compress/BZip2Decoder.h b/CPP/7zip/Compress/BZip2Decoder.h index 2c28c5a1..8703d572 100644 --- a/CPP/7zip/Compress/BZip2Decoder.h +++ b/CPP/7zip/Compress/BZip2Decoder.h @@ -154,10 +154,6 @@ public: 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(); @@ -166,6 +162,10 @@ public: CState m_States[1]; #endif + 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 SetRatioProgress(UInt64 packSize); diff --git a/CPP/7zip/Compress/BZip2Encoder.cpp b/CPP/7zip/Compress/BZip2Encoder.cpp index 2bdbe989..bd985dfe 100644 --- a/CPP/7zip/Compress/BZip2Encoder.cpp +++ b/CPP/7zip/Compress/BZip2Encoder.cpp @@ -13,10 +13,10 @@ namespace NCompress { namespace NBZip2 { -const int kMaxHuffmanLenForEncoding = 16; // it must be < kMaxHuffmanLen = 20 +const unsigned kMaxHuffmanLenForEncoding = 16; // it must be < kMaxHuffmanLen = 20 static const UInt32 kBufferSize = (1 << 17); -static const int kNumHuffPasses = 4; +static const unsigned kNumHuffPasses = 4; bool CThreadInfo::Alloc() { @@ -126,14 +126,16 @@ void CEncProps::Normalize(int level) { if (level < 0) level = 5; if (level > 9) level = 9; + if (NumPasses == (UInt32)(Int32)-1) NumPasses = (level >= 9 ? 7 : (level >= 7 ? 2 : 1)); - if (NumPasses < kBlockSizeMultMin) NumPasses = kBlockSizeMultMin; - if (NumPasses > kBlockSizeMultMax) NumPasses = kBlockSizeMultMax; + if (NumPasses < 1) NumPasses = 1; + if (NumPasses > kNumPassesMax) NumPasses = kNumPassesMax; + if (BlockSizeMult == (UInt32)(Int32)-1) BlockSizeMult = (level >= 5 ? 9 : (level >= 1 ? level * 2 - 1: 1)); - if (BlockSizeMult == 0) BlockSizeMult = 1; - if (BlockSizeMult > kNumPassesMax) BlockSizeMult = kNumPassesMax; + if (BlockSizeMult < kBlockSizeMultMin) BlockSizeMult = kBlockSizeMultMin; + if (BlockSizeMult > kBlockSizeMultMax) BlockSizeMult = kBlockSizeMultMax; } CEncoder::CEncoder() @@ -212,7 +214,7 @@ UInt32 CEncoder::ReadRleBlock(Byte *buffer) if (m_InStream.ReadByte(prevByte)) { UInt32 blockSize = _props.BlockSizeMult * kBlockSizeStep - 1; - int numReps = 1; + unsigned numReps = 1; buffer[i++] = prevByte; while (i < blockSize) // "- 1" to support RLE { @@ -246,19 +248,19 @@ UInt32 CEncoder::ReadRleBlock(Byte *buffer) 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::WriteBit2(Byte v) { WriteBits2(v, 1); } void CThreadInfo::WriteCrc2(UInt32 v) { - for (int i = 0; i < 4; i++) + for (unsigned i = 0; i < 4; i++) WriteByte2(((Byte)(v >> (24 - i * 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::WriteBit(Byte v) { WriteBits(v, 1); } void CEncoder::WriteCrc(UInt32 v) { - for (int i = 0; i < 4; i++) + for (unsigned i = 0; i < 4; i++) WriteByte(((Byte)(v >> (24 - i * 8)))); } @@ -266,7 +268,7 @@ void CEncoder::WriteCrc(UInt32 v) // blockSize > 0 void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) { - WriteBit2(false); // Randomised = false + WriteBit2(0); // Randomised = false { UInt32 origPtr = BlockSort(m_BlockSorterIndex, block, blockSize); @@ -276,21 +278,21 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) } CMtf8Encoder mtf; - int numInUse = 0; + unsigned numInUse = 0; { - bool inUse[256]; - bool inUse16[16]; + Byte inUse[256]; + Byte inUse16[16]; UInt32 i; for (i = 0; i < 256; i++) - inUse[i] = false; + inUse[i] = 0; for (i = 0; i < 16; i++) - inUse16[i] = false; + inUse16[i] = 0; for (i = 0; i < blockSize; i++) - inUse[block[i]] = true; + inUse[block[i]] = 1; for (i = 0; i < 256; i++) if (inUse[i]) { - inUse16[i >> 4] = true; + inUse16[i >> 4] = 1; mtf.Buf[numInUse++] = (Byte)i; } for (i = 0; i < 16; i++) @@ -299,13 +301,13 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) if (inUse16[i >> 4]) WriteBit2(inUse[i]); } - int alphaSize = numInUse + 2; + unsigned alphaSize = numInUse + 2; Byte *mtfs = m_MtfArray; UInt32 mtfArraySize = 0; UInt32 symbolCounts[kMaxAlphaSize]; { - for (int i = 0; i < kMaxAlphaSize; i++) + for (unsigned i = 0; i < kMaxAlphaSize; i++) symbolCounts[i] = 0; } @@ -360,17 +362,17 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) UInt32 numSymbols = 0; { - for (int i = 0; i < kMaxAlphaSize; i++) + for (unsigned i = 0; i < kMaxAlphaSize; i++) numSymbols += symbolCounts[i]; } - int bestNumTables = kNumTablesMin; + unsigned bestNumTables = kNumTablesMin; UInt32 bestPrice = 0xFFFFFFFF; UInt32 startPos = m_OutStreamCurrent->GetPos(); Byte startCurByte = m_OutStreamCurrent->GetCurByte(); - for (int nt = kNumTablesMin; nt <= kNumTablesMax + 1; nt++) + for (unsigned nt = kNumTablesMin; nt <= kNumTablesMax + 1; nt++) { - int numTables; + unsigned numTables; if (m_OptimizeNumTables) { @@ -397,21 +399,21 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) { UInt32 remFreq = numSymbols; - int gs = 0; - int t = numTables; + unsigned gs = 0; + unsigned t = numTables; do { UInt32 tFreq = remFreq / t; - int ge = gs; + unsigned ge = gs; UInt32 aFreq = 0; while (aFreq < tFreq) // && ge < alphaSize) aFreq += symbolCounts[ge++]; - if (ge - 1 > gs && t != numTables && t != 1 && (((numTables - t) & 1) == 1)) + if (ge > gs + 1 && t != numTables && t != 1 && (((numTables - t) & 1) == 1)) aFreq -= symbolCounts[--ge]; Byte *lens = Lens[t - 1]; - int i = 0; + unsigned i = 0; do lens[i] = (Byte)((i >= gs && i < ge) ? 0 : 1); while (++i < alphaSize); @@ -422,10 +424,10 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) } - for (int pass = 0; pass < kNumHuffPasses; pass++) + for (unsigned pass = 0; pass < kNumHuffPasses; pass++) { { - int t = 0; + unsigned t = 0; do memset(Freqs[t], 0, sizeof(Freqs[t])); while (++t < numTables); @@ -437,7 +439,7 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) do { UInt32 symbols[kGroupSize]; - int i = 0; + unsigned i = 0; do { UInt32 symbol = mtfs[mtfPos++]; @@ -448,12 +450,12 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) while (++i < kGroupSize && mtfPos < mtfArraySize); UInt32 bestPrice = 0xFFFFFFFF; - int t = 0; + unsigned t = 0; do { const Byte *lens = Lens[t]; UInt32 price = 0; - int j = 0; + unsigned j = 0; do price += lens[symbols[j]]; while (++j < i); @@ -465,7 +467,7 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) } while (++t < numTables); UInt32 *freqs = Freqs[m_Selectors[g++]]; - int j = 0; + unsigned j = 0; do freqs[symbols[j]]++; while (++j < i); @@ -473,11 +475,11 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) while (mtfPos < mtfArraySize); } - int t = 0; + unsigned t = 0; do { UInt32 *freqs = Freqs[t]; - int i = 0; + unsigned i = 0; do if (freqs[i] == 0) freqs[i] = 1; @@ -490,7 +492,7 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) { Byte mtfSel[kNumTablesMax]; { - int t = 0; + unsigned t = 0; do mtfSel[t] = (Byte)t; while (++t < numTables); @@ -500,10 +502,10 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) do { Byte sel = m_Selectors[i]; - int pos; + unsigned pos; for (pos = 0; mtfSel[pos] != sel; pos++) - WriteBit2(true); - WriteBit2(false); + WriteBit2(1); + WriteBit2(0); for (; pos > 0; pos--) mtfSel[pos] = mtfSel[pos - 1]; mtfSel[0] = sel; @@ -512,31 +514,31 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) } { - int t = 0; + unsigned t = 0; do { const Byte *lens = Lens[t]; UInt32 len = lens[0]; WriteBits2(len, kNumLevelsBits); - int i = 0; + unsigned i = 0; do { UInt32 level = lens[i]; while (len != level) { - WriteBit2(true); + WriteBit2(1); if (len < level) { - WriteBit2(false); + WriteBit2(0); len++; } else { - WriteBit2(true); + WriteBit2(1); len--; } } - WriteBit2(false); + WriteBit2(0); } while (++i < alphaSize); } @@ -557,7 +559,7 @@ void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) if (groupSize == 0) { groupSize = kGroupSize; - int t = m_Selectors[groupIndex++]; + unsigned t = m_Selectors[groupIndex++]; lens = Lens[t]; codes = Codes[t]; } @@ -591,7 +593,7 @@ UInt32 CThreadInfo::EncodeBlockWithHeaders(const Byte *block, UInt32 blockSize) WriteByte2(kBlockSig5); CBZip2Crc crc; - int numReps = 0; + unsigned numReps = 0; Byte prevByte = block[0]; UInt32 i = 0; do diff --git a/CPP/7zip/Compress/BZip2Encoder.h b/CPP/7zip/Compress/BZip2Encoder.h index 6b04eca1..bf05f59f 100644 --- a/CPP/7zip/Compress/BZip2Encoder.h +++ b/CPP/7zip/Compress/BZip2Encoder.h @@ -85,7 +85,7 @@ public: class CEncoder; -const int kNumPassesMax = 10; +const unsigned kNumPassesMax = 10; class CThreadInfo { @@ -111,7 +111,7 @@ private: void WriteBits2(UInt32 value, unsigned numBits); void WriteByte2(Byte b); - void WriteBit2(bool v); + void WriteBit2(Byte v); void WriteCrc2(UInt32 v); void EncodeBlock(const Byte *block, UInt32 blockSize); @@ -198,7 +198,7 @@ public: void WriteBits(UInt32 value, unsigned numBits); void WriteByte(Byte b); - void WriteBit(bool v); + // void WriteBit(Byte v); void WriteCrc(UInt32 v); #ifndef _7ZIP_ST diff --git a/CPP/7zip/Compress/BZip2Register.cpp b/CPP/7zip/Compress/BZip2Register.cpp index ef14204b..0dd6ec9a 100644 --- a/CPP/7zip/Compress/BZip2Register.cpp +++ b/CPP/7zip/Compress/BZip2Register.cpp @@ -6,15 +6,13 @@ #include "BZip2Decoder.h" -static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::NBZip2::CDecoder); } +REGISTER_CODEC_CREATE(CreateDec, NCompress::NBZip2::CDecoder) + #if !defined(EXTRACT_ONLY) && !defined(BZIP2_EXTRACT_ONLY) #include "BZip2Encoder.h" -static void *CreateCodecOut() { return (void *)(ICompressCoder *)(new NCompress::NBZip2::CEncoder); } +REGISTER_CODEC_CREATE(CreateEnc, NCompress::NBZip2::CEncoder) #else -#define CreateCodecOut 0 +#define CreateEnc NULL #endif -static CCodecInfo g_CodecInfo = - { CreateCodec, CreateCodecOut, 0x040202, L"BZip2", 1, false }; - -REGISTER_CODEC(BZip2) +REGISTER_CODEC_2(BZip2, CreateDec, CreateEnc, 0x40202, "BZip2") diff --git a/CPP/7zip/Compress/Bcj2Coder.cpp b/CPP/7zip/Compress/Bcj2Coder.cpp index 2d737e8a..fd7ce7ef 100644 --- a/CPP/7zip/Compress/Bcj2Coder.cpp +++ b/CPP/7zip/Compress/Bcj2Coder.cpp @@ -4,363 +4,655 @@ #include "../../../C/Alloc.h" +#include "../Common/StreamUtils.h" + #include "Bcj2Coder.h" namespace NCompress { namespace NBcj2 { -inline bool IsJcc(Byte b0, Byte b1) { return (b0 == 0x0F && (b1 & 0xF0) == 0x80); } -inline bool IsJ(Byte b0, Byte b1) { return ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)); } -inline unsigned GetIndex(Byte b0, Byte b1) { return ((b1 == 0xE8) ? b0 : ((b1 == 0xE9) ? 256 : 257)); } - -#ifndef EXTRACT_ONLY - -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)); +CBaseCoder::CBaseCoder() +{ + for (int i = 0; i < BCJ2_NUM_STREAMS + 1; i++) + { + _bufs[i] = NULL; + _bufsCurSizes[i] = 0; + _bufsNewSizes[i] = (1 << 18); + } +} -static bool inline Test86MSByte(Byte b) +CBaseCoder::~CBaseCoder() { - return (((b) + SIGN_BIT) & MASK_HIGH) == 0; + for (int i = 0; i < BCJ2_NUM_STREAMS + 1; i++) + ::MidFree(_bufs[i]); } -CEncoder::~CEncoder() +HRESULT CBaseCoder::Alloc(bool allocForOrig) { - ::MidFree(_buf); + unsigned num = allocForOrig ? BCJ2_NUM_STREAMS + 1 : BCJ2_NUM_STREAMS; + for (unsigned i = 0; i < num; i++) + { + UInt32 newSize = _bufsNewSizes[i]; + const UInt32 kMinBufSize = 1; + if (newSize < kMinBufSize) + newSize = kMinBufSize; + if (!_bufs[i] || newSize != _bufsCurSizes[i]) + { + if (_bufs[i]) + { + ::MidFree(_bufs[i]); + _bufs[i] = 0; + } + _bufsCurSizes[i] = 0; + Byte *buf = (Byte *)::MidAlloc(newSize); + _bufs[i] = buf; + if (!buf) + return E_OUTOFMEMORY; + _bufsCurSizes[i] = newSize; + } + } + return S_OK; } -HRESULT CEncoder::Flush() + + +#ifndef EXTRACT_ONLY + +CEncoder::CEncoder(): _relatLim(BCJ2_RELAT_LIMIT) {} +CEncoder::~CEncoder() {} + +STDMETHODIMP CEncoder::SetInBufSize(UInt32, UInt32 size) { _bufsNewSizes[BCJ2_NUM_STREAMS] = size; return S_OK; } +STDMETHODIMP CEncoder::SetOutBufSize(UInt32 streamIndex, UInt32 size) { _bufsNewSizes[streamIndex] = size; return S_OK; } + +STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) { - RINOK(_mainStream.Flush()); - RINOK(_callStream.Flush()); - RINOK(_jumpStream.Flush()); - _rc.FlushData(); - return _rc.FlushStream(); + UInt32 relatLim = BCJ2_RELAT_LIMIT; + + for (UInt32 i = 0; i < numProps; i++) + { + const PROPVARIANT &prop = props[i]; + PROPID propID = propIDs[i]; + if (propID >= NCoderPropID::kReduceSize) + continue; + switch (propID) + { + /* + case NCoderPropID::kDefaultProp: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + UInt32 v = prop.ulVal; + if (v > 31) + return E_INVALIDARG; + relatLim = (UInt32)1 << v; + break; + } + */ + case NCoderPropID::kDictionarySize: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + relatLim = prop.ulVal; + if (relatLim > ((UInt32)1 << 31)) + return E_INVALIDARG; + break; + } + + case NCoderPropID::kNumThreads: + continue; + case NCoderPropID::kLevel: + continue; + + default: return E_INVALIDARG; + } + } + + _relatLim = relatLim; + + return S_OK; } -HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams, - ISequentialOutStream **outStreams, const UInt64 ** /* outSizes */, UInt32 numOutStreams, + +HRESULT CEncoder::CodeReal(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, + ISequentialOutStream * const *outStreams, const UInt64 * const * /* outSizes */, UInt32 numOutStreams, ICompressProgressInfo *progress) { - if (numInStreams != 1 || numOutStreams != 4) + if (numInStreams != 1 || numOutStreams != BCJ2_NUM_STREAMS) return E_INVALIDARG; - 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) + RINOK(Alloc()); + + UInt32 fileSize_for_Conv = 0; + if (inSizes && inSizes[0]) { - _buf = (Byte *)MidAlloc(kBufSize); - if (_buf == 0) - return E_OUTOFMEMORY; + UInt64 inSize = *inSizes[0]; + if (inSize <= BCJ2_FileSize_MAX) + fileSize_for_Conv = (UInt32)inSize; } - bool sizeIsDefined = false; - UInt64 inSize = 0; - if (inSizes) - if (inSizes[0]) + CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize; + inStreams[0]->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize); + + CBcj2Enc enc; + + enc.src = _bufs[BCJ2_NUM_STREAMS]; + enc.srcLim = enc.src; + + { + for (int i = 0; i < BCJ2_NUM_STREAMS; i++) { - inSize = *inSizes[0]; - if (inSize <= kDefaultLimit) - sizeIsDefined = true; + enc.bufs[i] = _bufs[i]; + enc.lims[i] = _bufs[i] + _bufsCurSizes[i]; } + } - ISequentialInStream *inStream = inStreams[0]; + size_t numBytes_in_ReadBuf = 0; + UInt64 prevProgress = 0; + UInt64 totalStreamRead = 0; // size read from InputStream + UInt64 currentInPos = 0; // data that was processed, it doesn't include data in input buffer and data in enc.temp + UInt64 outSizeRc = 0; - _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(); + Bcj2Enc_Init(&enc); - CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize; - { - inStream->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize); - } + enc.fileIp = 0; + enc.fileSize = fileSize_for_Conv; - UInt32 nowPos = 0; - UInt64 nowPos64 = 0; - UInt32 bufPos = 0; + enc.relatLimit = _relatLim; - Byte prevByte = 0; + enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + bool needSubSize = false; UInt64 subStreamIndex = 0; UInt64 subStreamStartPos = 0; - UInt64 subStreamEndPos = 0; + bool readWasFinished = false; for (;;) { - UInt32 processedSize = 0; - for (;;) - { - UInt32 size = kBufSize - (bufPos + processedSize); - UInt32 processedSizeLoc; - if (size == 0) - break; - RINOK(inStream->Read(_buf + bufPos + processedSize, size, &processedSizeLoc)); - if (processedSizeLoc == 0) - break; - processedSize += processedSizeLoc; - } - UInt32 endPos = bufPos + processedSize; - - if (endPos < 5) - { - // change it - for (bufPos = 0; bufPos < endPos; bufPos++) - { - Byte b = _buf[bufPos]; - _mainStream.WriteByte(b); - UInt32 index; - if (b == 0xE8) - index = prevByte; - else if (b == 0xE9) - index = 256; - else if (IsJcc(prevByte, b)) - index = 257; - else - { - prevByte = b; - continue; - } - _statusEncoder[index].Encode(&_rc, 0); - prevByte = b; - } - return Flush(); - } - - bufPos = 0; - - UInt32 limit = endPos - 5; - while (bufPos <= limit) + if (needSubSize && getSubStreamSize) { - Byte b = _buf[bufPos]; - _mainStream.WriteByte(b); - if (!IsJ(prevByte, b)) + enc.fileIp = 0; + enc.fileSize = fileSize_for_Conv; + enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + + for (;;) { - bufPos++; - prevByte = b; - continue; - } - Byte nextByte = _buf[bufPos + 4]; - UInt32 src = - (UInt32(nextByte) << 24) | - (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) - { - UInt64 currentPos = (nowPos64 + bufPos); - while (subStreamEndPos < currentPos) + UInt64 subStreamSize = 0; + HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize); + needSubSize = false; + + if (result == S_OK) { - UInt64 subStreamSize; - HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize); - if (result == S_OK) + UInt64 newEndPos = subStreamStartPos + subStreamSize; + + bool isAccurateEnd = (newEndPos < totalStreamRead || + (newEndPos <= totalStreamRead && readWasFinished)); + + if (newEndPos <= currentInPos && isAccurateEnd) { - subStreamStartPos = subStreamEndPos; - subStreamEndPos += subStreamSize; + subStreamStartPos = newEndPos; subStreamIndex++; + continue; } - else if (result == S_FALSE || result == E_NOTIMPL) + + enc.srcLim = _bufs[BCJ2_NUM_STREAMS] + numBytes_in_ReadBuf; + + if (isAccurateEnd) { - getSubStreamSize.Release(); - subStreamStartPos = 0; - subStreamEndPos = subStreamStartPos - 1; + // data in enc.temp is possible here + size_t rem = (size_t)(totalStreamRead - newEndPos); + + /* Pos_of(enc.src) <= old newEndPos <= newEndPos + in another case, it's fail in some code */ + if ((size_t)(enc.srcLim - enc.src) < rem) + return E_FAIL; + + enc.srcLim -= rem; + enc.finishMode = BCJ2_ENC_FINISH_MODE_END_BLOCK; } - else - return result; - } - if (getSubStreamSize == NULL) - { - if (sizeIsDefined) - convert = (dest < inSize); - else - convert = Test86MSByte(nextByte); + + if (subStreamSize <= BCJ2_FileSize_MAX) + { + enc.fileIp = enc.ip + (UInt32)(subStreamStartPos - currentInPos); + enc.fileSize = (UInt32)subStreamSize; + } + break; } - else if (subStreamEndPos - subStreamStartPos > kDefaultLimit) - convert = Test86MSByte(nextByte); - else + + if (result == S_FALSE) + break; + if (result == E_NOTIMPL) { - UInt64 dest64 = (currentPos + 5) + Int64(Int32(src)); - convert = (dest64 >= subStreamStartPos && dest64 < subStreamEndPos); + getSubStreamSize.Release(); + break; } + return result; } - else if (sizeIsDefined) - convert = (dest < inSize); - else - convert = Test86MSByte(nextByte); - unsigned index = GetIndex(prevByte, b); - if (convert) + } + + if (readWasFinished && totalStreamRead - currentInPos == Bcj2Enc_Get_InputData_Size(&enc)) + enc.finishMode = BCJ2_ENC_FINISH_MODE_END_STREAM; + + Bcj2Enc_Encode(&enc); + + currentInPos = totalStreamRead - numBytes_in_ReadBuf + (enc.src - _bufs[BCJ2_NUM_STREAMS]) - enc.tempPos; + + if (Bcj2Enc_IsFinished(&enc)) + break; + + if (enc.state < BCJ2_NUM_STREAMS) + { + size_t curSize = enc.bufs[enc.state] - _bufs[enc.state]; + // printf("Write stream = %2d %6d\n", enc.state, curSize); + RINOK(WriteStream(outStreams[enc.state], _bufs[enc.state], curSize)); + if (enc.state == BCJ2_STREAM_RC) + outSizeRc += curSize; + + enc.bufs[enc.state] = _bufs[enc.state]; + enc.lims[enc.state] = _bufs[enc.state] + _bufsCurSizes[enc.state]; + } + else if (enc.state != BCJ2_ENC_STATE_ORIG) + return E_FAIL; + else + { + needSubSize = true; + + if (numBytes_in_ReadBuf != (size_t)(enc.src - _bufs[BCJ2_NUM_STREAMS])) { - _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)); - prevByte = nextByte; + enc.srcLim = _bufs[BCJ2_NUM_STREAMS] + numBytes_in_ReadBuf; + continue; } - else + + if (readWasFinished) + continue; + + numBytes_in_ReadBuf = 0; + enc.src = _bufs[BCJ2_NUM_STREAMS]; + enc.srcLim = _bufs[BCJ2_NUM_STREAMS]; + + UInt32 curSize = _bufsCurSizes[BCJ2_NUM_STREAMS]; + RINOK(inStreams[0]->Read(_bufs[BCJ2_NUM_STREAMS], curSize, &curSize)); + + // printf("Read %6d bytes\n", curSize); + if (curSize == 0) { - _statusEncoder[index].Encode(&_rc, 0); - bufPos++; - prevByte = b; + readWasFinished = true; + continue; } + + numBytes_in_ReadBuf = curSize; + totalStreamRead += numBytes_in_ReadBuf; + enc.srcLim = _bufs[BCJ2_NUM_STREAMS] + numBytes_in_ReadBuf; } - nowPos += bufPos; - nowPos64 += bufPos; - if (progress) + if (progress && currentInPos - prevProgress >= (1 << 20)) { - /* - const UInt64 compressedSize = - _mainStream.GetProcessedSize() + - _callStream.GetProcessedSize() + - _jumpStream.GetProcessedSize() + - _rc.GetProcessedSize(); - */ - RINOK(progress->SetRatioInfo(&nowPos64, NULL)); + UInt64 outSize2 = currentInPos + outSizeRc + enc.bufs[BCJ2_STREAM_RC] - enc.bufs[BCJ2_STREAM_RC]; + prevProgress = currentInPos; + // printf("progress %8d, %8d\n", (int)inSize2, (int)outSize2); + RINOK(progress->SetRatioInfo(¤tInPos, &outSize2)); } - - UInt32 i = 0; - while (bufPos < endPos) - _buf[i++] = _buf[bufPos++]; - bufPos = i; } + + for (int i = 0; i < BCJ2_NUM_STREAMS; i++) + { + RINOK(WriteStream(outStreams[i], _bufs[i], enc.bufs[i] - _bufs[i])); + } + + // if (currentInPos != subStreamStartPos + subStreamSize) return E_FAIL; + + return S_OK; } -STDMETHODIMP CEncoder::Code(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams, - ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams, +STDMETHODIMP CEncoder::Code(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, + ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, ICompressProgressInfo *progress) { try { return CodeReal(inStreams, inSizes, numInStreams, outStreams, outSizes,numOutStreams, progress); } - catch(const COutBufferException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } + catch(...) { return E_FAIL; } } #endif -STDMETHODIMP CDecoder::SetInBufSize(UInt32 streamIndex, UInt32 size) { _inBufSizes[streamIndex] = size; return S_OK; } -STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outBufSize = size; return S_OK; } -CDecoder::CDecoder(): - _outBufSize(1 << 16) + + + +STDMETHODIMP CDecoder::SetInBufSize(UInt32 streamIndex, UInt32 size) { _bufsNewSizes[streamIndex] = size; return S_OK; } +STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _bufsNewSizes[BCJ2_NUM_STREAMS] = size; return S_OK; } + +CDecoder::CDecoder(): _finishMode(false), _outSizeDefined(false), _outSize(0) +{} + +STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode) { - _inBufSizes[0] = 1 << 20; - _inBufSizes[1] = 1 << 20; - _inBufSizes[2] = 1 << 20; - _inBufSizes[3] = 1 << 20; + _finishMode = (finishMode != 0); + return S_OK; } -HRESULT CDecoder::CodeReal(ISequentialInStream **inStreams, const UInt64 ** /* inSizes */, UInt32 numInStreams, - ISequentialOutStream **outStreams, const UInt64 ** /* outSizes */, UInt32 numOutStreams, +void CDecoder::InitCommon() +{ + { + for (int i = 0; i < BCJ2_NUM_STREAMS; i++) + dec.lims[i] = dec.bufs[i] = _bufs[i]; + } + + { + for (int i = 0; i < BCJ2_NUM_STREAMS; i++) + { + _extraReadSizes[i] = 0; + _inStreamsProcessed[i] = 0; + _readRes[i] = S_OK; + } + } + + Bcj2Dec_Init(&dec); +} + +HRESULT CDecoder::Code(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, + ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, ICompressProgressInfo *progress) { - if (numInStreams != 4 || numOutStreams != 1) + if (numInStreams != BCJ2_NUM_STREAMS || numOutStreams != 1) return E_INVALIDARG; - 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; - - _mainStream.SetStream(inStreams[0]); - _callStream.SetStream(inStreams[1]); - _jumpStream.SetStream(inStreams[2]); - _rc.SetStream(inStreams[3]); - _outStream.SetStream(outStreams[0]); - - _mainStream.Init(); - _callStream.Init(); - _jumpStream.Init(); - _rc.Init(); - _outStream.Init(); - - for (unsigned i = 0; i < 256 + 2; i++) - _statusDecoder[i].Init(); - - Byte prevByte = 0; - UInt32 processedBytes = 0; + RINOK(Alloc()); + + InitCommon(); + + dec.destLim = dec.dest = _bufs[BCJ2_NUM_STREAMS]; + + UInt64 outSizeProcessed = 0; + UInt64 prevProgress = 0; + + HRESULT res = S_OK; + for (;;) { - if (processedBytes >= (1 << 20) && progress) + if (Bcj2Dec_Decode(&dec) != SZ_OK) + return S_FALSE; + + if (dec.state < BCJ2_NUM_STREAMS) { - /* - const UInt64 compressedSize = - _mainStream.GetProcessedSize() + - _callStream.GetProcessedSize() + - _jumpStream.GetProcessedSize() + - _rc.GetProcessedSize(); - */ - const UInt64 nowPos64 = _outStream.GetProcessedSize(); - RINOK(progress->SetRatioInfo(NULL, &nowPos64)); - processedBytes = 0; + size_t totalRead = _extraReadSizes[dec.state]; + { + Byte *buf = _bufs[dec.state]; + for (size_t i = 0; i < totalRead; i++) + buf[i] = dec.bufs[dec.state][i]; + dec.lims[dec.state] = + dec.bufs[dec.state] = buf; + } + + if (_readRes[dec.state] != S_OK) + { + res = _readRes[dec.state]; + break; + } + + do + { + UInt32 curSize = _bufsCurSizes[dec.state] - (UInt32)totalRead; + /* + we want to call Read even even if size is 0 + if (inSizes && inSizes[dec.state]) + { + UInt64 rem = *inSizes[dec.state] - _inStreamsProcessed[dec.state]; + if (curSize > rem) + curSize = (UInt32)rem; + } + */ + + HRESULT res2 = inStreams[dec.state]->Read(_bufs[dec.state] + totalRead, curSize, &curSize); + _readRes[dec.state] = res2; + if (curSize == 0) + break; + _inStreamsProcessed[dec.state] += curSize; + totalRead += curSize; + if (res2 != S_OK) + break; + } + while (totalRead < 4 && BCJ2_IS_32BIT_STREAM(dec.state)); + + if (_readRes[dec.state] != S_OK) + res = _readRes[dec.state]; + + if (totalRead == 0) + break; + + // res == S_OK; + + if (BCJ2_IS_32BIT_STREAM(dec.state)) + { + unsigned extraSize = ((unsigned)totalRead & 3); + _extraReadSizes[dec.state] = extraSize; + if (totalRead < 4) + { + res = (_readRes[dec.state] != S_OK) ? _readRes[dec.state] : S_FALSE; + break; + } + totalRead -= extraSize; + } + + dec.lims[dec.state] = _bufs[dec.state] + totalRead; } - UInt32 i; - Byte b = 0; - const UInt32 kBurstSize = (1 << 18); - for (i = 0; i < kBurstSize; i++) + else // if (dec.state <= BCJ2_STATE_ORIG) { - if (!_mainStream.ReadByte(b)) - return _outStream.Flush(); - _outStream.WriteByte(b); - if (IsJ(prevByte, b)) - break; - prevByte = b; + size_t curSize = dec.dest - _bufs[BCJ2_NUM_STREAMS]; + if (curSize != 0) + { + outSizeProcessed += curSize; + RINOK(WriteStream(outStreams[0], _bufs[BCJ2_NUM_STREAMS], curSize)); + } + dec.dest = _bufs[BCJ2_NUM_STREAMS]; + { + size_t rem = _bufsCurSizes[BCJ2_NUM_STREAMS]; + if (outSizes && outSizes[0]) + { + UInt64 outSize = *outSizes[0] - outSizeProcessed; + if (rem > outSize) + rem = (size_t)outSize; + } + dec.destLim = dec.dest + rem; + if (rem == 0) + break; + } } - processedBytes += i; - if (i == kBurstSize) - continue; - unsigned index = GetIndex(prevByte, b); - if (_statusDecoder[index].Decode(&_rc) == 1) + + if (progress) { - UInt32 src = 0; - CInBuffer &s = (b == 0xE8) ? _callStream : _jumpStream; - for (unsigned i = 0; i < 4; i++) + UInt64 outSize2 = outSizeProcessed + (dec.dest - _bufs[BCJ2_NUM_STREAMS]); + if (outSize2 - prevProgress >= (1 << 22)) { - Byte b0; - if (!s.ReadByte(b0)) + UInt64 inSize2 = outSize2 + _inStreamsProcessed[BCJ2_STREAM_RC] - (dec.lims[BCJ2_STREAM_RC] - dec.bufs[BCJ2_STREAM_RC]); + RINOK(progress->SetRatioInfo(&inSize2, &outSize2)); + prevProgress = outSize2; + } + } + } + + size_t curSize = dec.dest - _bufs[BCJ2_NUM_STREAMS]; + if (curSize != 0) + { + outSizeProcessed += curSize; + RINOK(WriteStream(outStreams[0], _bufs[BCJ2_NUM_STREAMS], curSize)); + } + + if (res != S_OK) + return res; + + if (_finishMode) + { + if (!Bcj2Dec_IsFinished(&dec)) + return S_FALSE; + + // we still allow the cases when input streams are larger than required for decoding. + // so the case (dec.state == BCJ2_STATE_ORIG) is also allowed, if MAIN stream is larger than required. + if (dec.state != BCJ2_STREAM_MAIN && + dec.state != BCJ2_DEC_STATE_ORIG) + return S_FALSE; + + if (inSizes) + { + for (int i = 0; i < BCJ2_NUM_STREAMS; i++) + { + size_t rem = dec.lims[i] - dec.bufs[i] + _extraReadSizes[i]; + /* + if (rem != 0) + return S_FALSE; + */ + if (inSizes[i] && *inSizes[i] != _inStreamsProcessed[i] - rem) return S_FALSE; - src <<= 8; - src |= ((UInt32)b0); } - UInt32 dest = src - (UInt32(_outStream.GetProcessedSize()) + 4) ; - _outStream.WriteByte((Byte)(dest)); - _outStream.WriteByte((Byte)(dest >> 8)); - _outStream.WriteByte((Byte)(dest >> 16)); - _outStream.WriteByte((Byte)(dest >> 24)); - prevByte = (Byte)(dest >> 24); - processedBytes += 4; } - else - prevByte = b; } + + return S_OK; } -STDMETHODIMP CDecoder::Code(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams, - ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams, - ICompressProgressInfo *progress) +STDMETHODIMP CDecoder::SetInStream2(UInt32 streamIndex, ISequentialInStream *inStream) { - try + inStreams[streamIndex] = inStream; + return S_OK; +} + +STDMETHODIMP CDecoder::ReleaseInStream2(UInt32 streamIndex) +{ + inStreams[streamIndex].Release(); + return S_OK; +} + +STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) +{ + _outSizeDefined = (outSize != NULL); + _outSize = 0; + if (_outSizeDefined) + _outSize = *outSize; + + _outSize_Processed = 0; + + HRESULT res = Alloc(false); + + InitCommon(); + dec.destLim = dec.dest = NULL; + + return res; +} + + +STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize) + *processedSize = 0; + + if (size == 0) + return S_OK; + + UInt32 totalProcessed = 0; + + if (_outSizeDefined) { - return CodeReal(inStreams, inSizes, numInStreams, outStreams, outSizes,numOutStreams, progress); + UInt64 rem = _outSize - _outSize_Processed; + if (size > rem) + size = (UInt32)rem; + } + dec.dest = (Byte *)data; + dec.destLim = (const Byte *)data + size; + + HRESULT res = S_OK; + + for (;;) + { + SRes sres = Bcj2Dec_Decode(&dec); + if (sres != SZ_OK) + return S_FALSE; + + { + UInt32 curSize = (UInt32)(dec.dest - (Byte *)data); + if (curSize != 0) + { + totalProcessed += curSize; + if (processedSize) + *processedSize = totalProcessed; + data = (void *)((Byte *)data + curSize); + size -= curSize; + _outSize_Processed += curSize; + } + } + + if (dec.state >= BCJ2_NUM_STREAMS) + break; + + { + size_t totalRead = _extraReadSizes[dec.state]; + { + Byte *buf = _bufs[dec.state]; + for (size_t i = 0; i < totalRead; i++) + buf[i] = dec.bufs[dec.state][i]; + dec.lims[dec.state] = + dec.bufs[dec.state] = buf; + } + + if (_readRes[dec.state] != S_OK) + return _readRes[dec.state]; + + do + { + UInt32 curSize = _bufsCurSizes[dec.state] - (UInt32)totalRead; + HRESULT res2 = inStreams[dec.state]->Read(_bufs[dec.state] + totalRead, curSize, &curSize); + _readRes[dec.state] = res2; + if (curSize == 0) + break; + _inStreamsProcessed[dec.state] += curSize; + totalRead += curSize; + if (res2 != S_OK) + break; + } + while (totalRead < 4 && BCJ2_IS_32BIT_STREAM(dec.state)); + + if (totalRead == 0) + { + if (totalProcessed == 0) + res = _readRes[dec.state]; + break; + } + + if (BCJ2_IS_32BIT_STREAM(dec.state)) + { + unsigned extraSize = ((unsigned)totalRead & 3); + _extraReadSizes[dec.state] = extraSize; + if (totalRead < 4) + { + if (totalProcessed != 0) + return S_OK; + return (_readRes[dec.state] != S_OK) ? _readRes[dec.state] : S_FALSE; + } + totalRead -= extraSize; + } + + dec.lims[dec.state] = _bufs[dec.state] + totalRead; + } + } + + if (_finishMode && _outSizeDefined && _outSize == _outSize_Processed) + { + if (!Bcj2Dec_IsFinished(&dec)) + return S_FALSE; + + if (dec.state != BCJ2_STREAM_MAIN && + dec.state != BCJ2_DEC_STATE_ORIG) + return S_FALSE; + + /* + for (int i = 0; i < BCJ2_NUM_STREAMS; i++) + if (dec.bufs[i] != dec.lims[i] || _extraReadSizes[i] != 0) + return S_FALSE; + */ } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(const COutBufferException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } + + return res; } }} diff --git a/CPP/7zip/Compress/Bcj2Coder.h b/CPP/7zip/Compress/Bcj2Coder.h index d2b3bda3..627e505d 100644 --- a/CPP/7zip/Compress/Bcj2Coder.h +++ b/CPP/7zip/Compress/Bcj2Coder.h @@ -3,44 +3,57 @@ #ifndef __COMPRESS_BCJ2_CODER_H #define __COMPRESS_BCJ2_CODER_H +#include "../../../C/Bcj2.h" + #include "../../Common/MyCom.h" #include "../ICoder.h" -#include "RangeCoderBit.h" - namespace NCompress { namespace NBcj2 { -const unsigned kNumMoveBits = 5; +class CBaseCoder +{ +protected: + Byte *_bufs[BCJ2_NUM_STREAMS + 1]; + UInt32 _bufsCurSizes[BCJ2_NUM_STREAMS + 1]; + UInt32 _bufsNewSizes[BCJ2_NUM_STREAMS + 1]; + + HRESULT Alloc(bool allocForOrig = true); +public: + CBaseCoder(); + ~CBaseCoder(); +}; + #ifndef EXTRACT_ONLY class CEncoder: public ICompressCoder2, - public CMyUnknownImp + public ICompressSetCoderProperties, + public ICompressSetBufSize, + public CMyUnknownImp, + public CBaseCoder { - Byte *_buf; - - COutBuffer _mainStream; - COutBuffer _callStream; - COutBuffer _jumpStream; - NRangeCoder::CEncoder _rc; - NRangeCoder::CBitEncoder<kNumMoveBits> _statusEncoder[256 + 2]; + UInt32 _relatLim; - HRESULT Flush(); + HRESULT CodeReal(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, + ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, + ICompressProgressInfo *progress); public: - MY_UNKNOWN_IMP + MY_UNKNOWN_IMP3(ICompressCoder2, ICompressSetCoderProperties, ICompressSetBufSize) - HRESULT CodeReal(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams, - ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams, - ICompressProgressInfo *progress); - STDMETHOD(Code)(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams, - ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams, + STDMETHOD(Code)(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, + ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, ICompressProgressInfo *progress); + + STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - CEncoder(): _buf(0) {}; + STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); + STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); + + CEncoder(); ~CEncoder(); }; @@ -48,29 +61,51 @@ public: class CDecoder: public ICompressCoder2, + public ICompressSetFinishMode, + public ICompressSetInStream2, + public ISequentialInStream, + public ICompressSetOutStreamSize, public ICompressSetBufSize, - public CMyUnknownImp + public CMyUnknownImp, + public CBaseCoder { - CInBuffer _mainStream; - CInBuffer _callStream; - CInBuffer _jumpStream; - NRangeCoder::CDecoder _rc; - NRangeCoder::CBitDecoder<kNumMoveBits> _statusDecoder[256 + 2]; - - COutBuffer _outStream; - UInt32 _inBufSizes[4]; - UInt32 _outBufSize; - + unsigned _extraReadSizes[BCJ2_NUM_STREAMS]; + UInt64 _inStreamsProcessed[BCJ2_NUM_STREAMS]; + HRESULT _readRes[BCJ2_NUM_STREAMS]; + CMyComPtr<ISequentialInStream> inStreams[BCJ2_NUM_STREAMS]; + + bool _finishMode; + bool _outSizeDefined; + UInt64 _outSize; + UInt64 _outSize_Processed; + CBcj2Dec dec; + + void InitCommon(); + // HRESULT ReadSpec(); + public: - MY_UNKNOWN_IMP1(ICompressSetBufSize); + MY_UNKNOWN_IMP6( + ICompressCoder2, + ICompressSetFinishMode, + ICompressSetInStream2, + ISequentialInStream, + ICompressSetOutStreamSize, + ICompressSetBufSize + ); - HRESULT CodeReal(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams, - ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams, - ICompressProgressInfo *progress); - STDMETHOD(Code)(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams, - ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams, + STDMETHOD(Code)(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, + ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, ICompressProgressInfo *progress); + STDMETHOD(SetFinishMode)(UInt32 finishMode); + + STDMETHOD(SetInStream2)(UInt32 streamIndex, ISequentialInStream *inStream); + STDMETHOD(ReleaseInStream2)(UInt32 streamIndex); + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); + STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); diff --git a/CPP/7zip/Compress/Bcj2Register.cpp b/CPP/7zip/Compress/Bcj2Register.cpp index 8eb1e736..ef37ae0c 100644 --- a/CPP/7zip/Compress/Bcj2Register.cpp +++ b/CPP/7zip/Compress/Bcj2Register.cpp @@ -6,14 +6,14 @@ #include "Bcj2Coder.h" -static void *CreateCodec() { return (void *)(ICompressCoder2 *)(new NCompress::NBcj2::CDecoder()); } +REGISTER_CODEC_CREATE_2(CreateCodec, NCompress::NBcj2::CDecoder(), ICompressCoder2) #ifndef EXTRACT_ONLY -static void *CreateCodecOut() { return (void *)(ICompressCoder2 *)(new NCompress::NBcj2::CEncoder()); } +REGISTER_CODEC_CREATE_2(CreateCodecOut, NCompress::NBcj2::CEncoder(), ICompressCoder2) #else -#define CreateCodecOut 0 +#define CreateCodecOut NULL #endif -static CCodecInfo g_CodecInfo = - { CreateCodec, CreateCodecOut, 0x0303011B, L"BCJ2", 4, false }; +REGISTER_CODEC_VAR + { CreateCodec, CreateCodecOut, 0x303011B, "BCJ2", 4, false }; REGISTER_CODEC(BCJ2) diff --git a/CPP/7zip/Compress/BcjCoder.cpp b/CPP/7zip/Compress/BcjCoder.cpp index 0e34ef48..37815dce 100644 --- a/CPP/7zip/Compress/BcjCoder.cpp +++ b/CPP/7zip/Compress/BcjCoder.cpp @@ -4,12 +4,16 @@ #include "BcjCoder.h" -UInt32 CBCJ_x86_Encoder::SubFilter(Byte *data, UInt32 size) +STDMETHODIMP CBcjCoder::Init() { - return (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, 1); + _bufferPos = 0; + x86_Convert_Init(_prevMask); + return S_OK; } -UInt32 CBCJ_x86_Decoder::SubFilter(Byte *data, UInt32 size) +STDMETHODIMP_(UInt32) CBcjCoder::Filter(Byte *data, UInt32 size) { - return (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, 0); + UInt32 processed = (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, _encode); + _bufferPos += processed; + return processed; } diff --git a/CPP/7zip/Compress/BcjCoder.h b/CPP/7zip/Compress/BcjCoder.h index 0754bcd2..275fd4f2 100644 --- a/CPP/7zip/Compress/BcjCoder.h +++ b/CPP/7zip/Compress/BcjCoder.h @@ -5,15 +5,22 @@ #include "../../../C/Bra.h" -#include "BranchCoder.h" +#include "../../Common/MyCom.h" -struct CBranch86 +#include "../ICoder.h" + +class CBcjCoder: + public ICompressFilter, + public CMyUnknownImp { + UInt32 _bufferPos; UInt32 _prevMask; - void x86Init() { x86_Convert_Init(_prevMask); } -}; + int _encode; +public: + MY_UNKNOWN_IMP; + INTERFACE_ICompressFilter(;) -MyClassB(BCJ_x86, 0x01, 3, CBranch86 , - virtual void SubInit() { x86Init(); }) + CBcjCoder(int encode): _bufferPos(0), _encode(encode) { x86_Convert_Init(_prevMask); } +}; #endif diff --git a/CPP/7zip/Compress/BcjRegister.cpp b/CPP/7zip/Compress/BcjRegister.cpp index 648ad8e0..83c6830f 100644 --- a/CPP/7zip/Compress/BcjRegister.cpp +++ b/CPP/7zip/Compress/BcjRegister.cpp @@ -6,14 +6,7 @@ #include "BcjCoder.h" -static void *CreateCodec() { return (void *)(ICompressFilter *)(new CBCJ_x86_Decoder()); } -#ifndef EXTRACT_ONLY -static void *CreateCodecOut() { return (void *)(ICompressFilter *)(new CBCJ_x86_Encoder()); } -#else -#define CreateCodecOut 0 -#endif - -static CCodecInfo g_CodecInfo = - { CreateCodec, CreateCodecOut, 0x03030103, L"BCJ", 1, true }; - -REGISTER_CODEC(BCJ) +REGISTER_FILTER_E(BCJ, + CBcjCoder(false), + CBcjCoder(true), + 0x3030103, "BCJ") diff --git a/CPP/7zip/Compress/BitmDecoder.h b/CPP/7zip/Compress/BitmDecoder.h index fef20e06..9b1c540e 100644 --- a/CPP/7zip/Compress/BitmDecoder.h +++ b/CPP/7zip/Compress/BitmDecoder.h @@ -72,7 +72,22 @@ public: return res; } + /* + unsigned ReadBit() + { + UInt32 res = ((_value >> (8 - _bitPos)) & kMask) >> (kNumValueBits - 1); + if (++_bitPos >= 8) + { + _value = (_value << 8) | _stream.ReadByte(); + _bitPos -= 8; + } + return (unsigned)res; + } + */ + void AlignToByte() { MovePos((kNumBigValueBits - _bitPos) & 7); } + + UInt32 ReadAlignBits() { return ReadBits((kNumBigValueBits - _bitPos) & 7); } }; } diff --git a/CPP/7zip/Compress/BranchCoder.cpp b/CPP/7zip/Compress/BranchCoder.cpp deleted file mode 100644 index 43170952..00000000 --- a/CPP/7zip/Compress/BranchCoder.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// BranchCoder.cpp - -#include "StdAfx.h" - -#include "BranchCoder.h" - -STDMETHODIMP CBranchConverter::Init() -{ - _bufferPos = 0; - SubInit(); - return S_OK; -} - -STDMETHODIMP_(UInt32) CBranchConverter::Filter(Byte *data, UInt32 size) -{ - UInt32 processedSize = SubFilter(data, size); - _bufferPos += processedSize; - return processedSize; -} diff --git a/CPP/7zip/Compress/BranchCoder.h b/CPP/7zip/Compress/BranchCoder.h deleted file mode 100644 index 0e3a5c4e..00000000 --- a/CPP/7zip/Compress/BranchCoder.h +++ /dev/null @@ -1,44 +0,0 @@ -// BranchCoder.h - -#ifndef __COMPRESS_BRANCH_CODER_H -#define __COMPRESS_BRANCH_CODER_H - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -class CBranchConverter: - public ICompressFilter, - public CMyUnknownImp -{ -protected: - UInt32 _bufferPos; - virtual void SubInit() {} - virtual UInt32 SubFilter(Byte *data, UInt32 size) = 0; -public: - MY_UNKNOWN_IMP; - STDMETHOD(Init)(); - STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); -}; - -#define MyClassEncoderA(Name) class C ## Name: public CBranchConverter \ - { public: UInt32 SubFilter(Byte *data, UInt32 size); }; - -#define MyClassDecoderA(Name) class C ## Name: public CBranchConverter \ - { public: UInt32 SubFilter(Byte *data, UInt32 size); }; - -#define MyClassEncoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \ - { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT}; - -#define MyClassDecoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \ - { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT}; - -#define MyClassA(Name, id, subId) \ -MyClassEncoderA(Name ## _Encoder) \ -MyClassDecoderA(Name ## _Decoder) - -#define MyClassB(Name, id, subId, ADD_ITEMS, ADD_INIT) \ -MyClassEncoderB(Name ## _Encoder, ADD_ITEMS, ADD_INIT) \ -MyClassDecoderB(Name ## _Decoder, ADD_ITEMS, ADD_INIT) - -#endif diff --git a/CPP/7zip/Compress/BranchMisc.cpp b/CPP/7zip/Compress/BranchMisc.cpp index 239f2513..0bf39b79 100644 --- a/CPP/7zip/Compress/BranchMisc.cpp +++ b/CPP/7zip/Compress/BranchMisc.cpp @@ -2,20 +2,17 @@ #include "StdAfx.h" -#include "../../../C/Bra.h" - #include "BranchMisc.h" -#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) \ +STDMETHODIMP CBranchCoder::Init() +{ + _bufferPos = 0; + return S_OK; +} -SUB_FILTER_IMP(ARM_) -SUB_FILTER_IMP(ARMT_) -SUB_FILTER_IMP(PPC_) -SUB_FILTER_IMP(SPARC_) -SUB_FILTER_IMP(IA64_) +STDMETHODIMP_(UInt32) CBranchCoder::Filter(Byte *data, UInt32 size) +{ + UInt32 processed = (UInt32)BraFunc(data, size, _bufferPos, _encode); + _bufferPos += processed; + return processed; +} diff --git a/CPP/7zip/Compress/BranchMisc.h b/CPP/7zip/Compress/BranchMisc.h index 81198b21..bbb5add9 100644 --- a/CPP/7zip/Compress/BranchMisc.h +++ b/CPP/7zip/Compress/BranchMisc.h @@ -3,12 +3,28 @@ #ifndef __COMPRESS_BRANCH_MISC_H #define __COMPRESS_BRANCH_MISC_H -#include "BranchCoder.h" +#include "../../Common/MyCom.h" -MyClassA(BC_ARM, 0x05, 1) -MyClassA(BC_ARMT, 0x07, 1) -MyClassA(BC_PPC, 0x02, 5) -MyClassA(BC_SPARC, 0x08, 5) -MyClassA(BC_IA64, 0x04, 1) +#include "../ICoder.h" + +EXTERN_C_BEGIN + +typedef SizeT (*Func_Bra)(Byte *data, SizeT size, UInt32 ip, int encoding); + +EXTERN_C_END + +class CBranchCoder: + public ICompressFilter, + public CMyUnknownImp +{ + UInt32 _bufferPos; + int _encode; + Func_Bra BraFunc; +public: + MY_UNKNOWN_IMP; + INTERFACE_ICompressFilter(;) + + CBranchCoder(Func_Bra bra, int encode): _bufferPos(0), _encode(encode), BraFunc(bra) {} +}; #endif diff --git a/CPP/7zip/Compress/BranchRegister.cpp b/CPP/7zip/Compress/BranchRegister.cpp index 380828c6..e1fcff6d 100644 --- a/CPP/7zip/Compress/BranchRegister.cpp +++ b/CPP/7zip/Compress/BranchRegister.cpp @@ -2,29 +2,35 @@ #include "StdAfx.h" +#include "../../../C/Bra.h" + #include "../Common/RegisterCodec.h" #include "BranchMisc.h" -#define CREATE_CODEC(x) \ - static void *CreateCodec ## x() { return (void *)(ICompressFilter *)(new C ## x ## _Decoder); } \ - static void *CreateCodec ## x ## Out() { return (void *)(ICompressFilter *)(new C ## x ## _Encoder); } +#define CREATE_BRA(n) \ + REGISTER_FILTER_CREATE(CreateBra_Decoder_ ## n, CBranchCoder(n ## _Convert, false)) \ + REGISTER_FILTER_CREATE(CreateBra_Encoder_ ## n, CBranchCoder(n ## _Convert, true)) \ -CREATE_CODEC(BC_PPC) -CREATE_CODEC(BC_IA64) -CREATE_CODEC(BC_ARM) -CREATE_CODEC(BC_ARMT) -CREATE_CODEC(BC_SPARC) +CREATE_BRA(PPC) +CREATE_BRA(IA64) +CREATE_BRA(ARM) +CREATE_BRA(ARMT) +CREATE_BRA(SPARC) -#define METHOD_ITEM(x, id1, id2, name) { CreateCodec ## x, CreateCodec ## x ## Out, 0x03030000 + (id1 * 256) + id2, name, 1, true } +#define METHOD_ITEM(n, id, name) \ + REGISTER_FILTER_ITEM( \ + CreateBra_Decoder_ ## n, \ + CreateBra_Encoder_ ## n, \ + 0x3030000 + id, name) -static CCodecInfo g_CodecsInfo[] = +REGISTER_CODECS_VAR { - METHOD_ITEM(BC_PPC, 0x02, 0x05, L"PPC"), - METHOD_ITEM(BC_IA64, 0x04, 1, L"IA64"), - METHOD_ITEM(BC_ARM, 0x05, 1, L"ARM"), - METHOD_ITEM(BC_ARMT, 0x07, 1, L"ARMT"), - METHOD_ITEM(BC_SPARC, 0x08, 0x05, L"SPARC") + METHOD_ITEM(PPC, 0x205, "PPC"), + METHOD_ITEM(IA64, 0x401, "IA64"), + METHOD_ITEM(ARM, 0x501, "ARM"), + METHOD_ITEM(ARMT, 0x701, "ARMT"), + METHOD_ITEM(SPARC, 0x805, "SPARC") }; REGISTER_CODECS(Branch) diff --git a/CPP/7zip/Compress/ByteSwap.cpp b/CPP/7zip/Compress/ByteSwap.cpp index 645b6ffc..f5620d6c 100644 --- a/CPP/7zip/Compress/ByteSwap.cpp +++ b/CPP/7zip/Compress/ByteSwap.cpp @@ -14,8 +14,7 @@ class CByteSwap2: { public: MY_UNKNOWN_IMP - STDMETHOD(Init)(); - STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + INTERFACE_ICompressFilter(;) }; class CByteSwap4: @@ -24,8 +23,7 @@ class CByteSwap4: { public: MY_UNKNOWN_IMP - STDMETHOD(Init)(); - STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + INTERFACE_ICompressFilter(;) }; STDMETHODIMP CByteSwap2::Init() { return S_OK; } @@ -33,14 +31,22 @@ STDMETHODIMP CByteSwap2::Init() { return S_OK; } STDMETHODIMP_(UInt32) CByteSwap2::Filter(Byte *data, UInt32 size) { const UInt32 kStep = 2; - UInt32 i; - for (i = 0; i + kStep <= size; i += kStep) + if (size < kStep) + return 0; + size &= ~(kStep - 1); + + const Byte *end = data + (size_t)size; + + do { - Byte b = data[i]; - data[i] = data[i + 1]; - data[i + 1] = b; + Byte b0 = data[0]; + data[0] = data[1]; + data[1] = b0; + data += kStep; } - return i; + while (data != end); + + return size; } STDMETHODIMP CByteSwap4::Init() { return S_OK; } @@ -48,26 +54,34 @@ STDMETHODIMP CByteSwap4::Init() { return S_OK; } STDMETHODIMP_(UInt32) CByteSwap4::Filter(Byte *data, UInt32 size) { const UInt32 kStep = 4; - UInt32 i; - for (i = 0; i + kStep <= size; i += kStep) + if (size < kStep) + return 0; + size &= ~(kStep - 1); + + const Byte *end = data + (size_t)size; + + do { - Byte b0 = data[i]; - Byte b1 = data[i + 1]; - data[i] = data[i + 3]; - data[i + 1] = data[i + 2]; - data[i + 2] = b1; - data[i + 3] = b0; + Byte b0 = data[0]; + Byte b1 = data[1]; + data[0] = data[3]; + data[1] = data[2]; + data[2] = b1; + data[3] = b0; + data += kStep; } - return i; + while (data != end); + + return size; } -static void *CreateCodec2() { return (void *)(ICompressFilter *)(new CByteSwap2); } -static void *CreateCodec4() { return (void *)(ICompressFilter *)(new CByteSwap4); } +REGISTER_FILTER_CREATE(CreateFilter2, CByteSwap2()) +REGISTER_FILTER_CREATE(CreateFilter4, CByteSwap4()) -static CCodecInfo g_CodecsInfo[] = +REGISTER_CODECS_VAR { - { CreateCodec2, CreateCodec2, 0x020302, L"Swap2", 1, true }, - { CreateCodec4, CreateCodec4, 0x020304, L"Swap4", 1, true } + REGISTER_FILTER_ITEM(CreateFilter2, CreateFilter2, 0x20302, "Swap2"), + REGISTER_FILTER_ITEM(CreateFilter4, CreateFilter4, 0x20304, "Swap4") }; REGISTER_CODECS(ByteSwap) diff --git a/CPP/7zip/Compress/CodecExports.cpp b/CPP/7zip/Compress/CodecExports.cpp index 726d35fc..019cb3c1 100644 --- a/CPP/7zip/Compress/CodecExports.cpp +++ b/CPP/7zip/Compress/CodecExports.cpp @@ -7,118 +7,164 @@ #include "../../Common/ComTry.h" #include "../../Common/MyCom.h" +#include "../../Windows/Defs.h" #include "../../Windows/PropVariant.h" #include "../ICoder.h" #include "../Common/RegisterCodec.h" -extern unsigned int g_NumCodecs; +extern unsigned g_NumCodecs; extern const CCodecInfo *g_Codecs[]; -extern unsigned int g_NumHashers; +extern unsigned 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, 0, 0, 0, 0, 0, 0, 0, 0); - -static inline HRESULT SetPropString(const char *s, unsigned int size, PROPVARIANT *value) +static void SetPropFromAscii(const char *s, PROPVARIANT *prop) throw() { - if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0) - value->vt = VT_BSTR; - return S_OK; + UINT len = (UINT)strlen(s); + OLECHAR *dest = ::SysAllocStringLen(NULL, len); + if (dest) + { + for (UINT i = 0; i <= len; i++) + dest[i] = (Byte)s[i]; + prop->bstrVal = dest; + prop->vt = VT_BSTR; + } } -static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value) +static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value) throw() { - return SetPropString((const char *)&guid, sizeof(GUID), value); + if ((value->bstrVal = ::SysAllocStringByteLen((const char *)&guid, sizeof(guid))) != NULL) + value->vt = VT_BSTR; + return S_OK; } -static HRESULT SetClassID(CMethodId id, UInt16 typeId, PROPVARIANT *value) +static HRESULT MethodToClassID(UInt16 typeId, CMethodId id, PROPVARIANT *value) throw() { GUID clsId; - clsId.Data1 = CLSID_CCodec.Data1; - clsId.Data2 = CLSID_CCodec.Data2; + clsId.Data1 = k_7zip_GUID_Data1; + clsId.Data2 = k_7zip_GUID_Data2; clsId.Data3 = typeId; SetUi64(clsId.Data4, id); return SetPropGUID(clsId, value); } -static HRESULT FindCodecClassId(const GUID *clsID, UInt32 isCoder2, bool isFilter, bool &encode, int &index) +static HRESULT FindCodecClassId(const GUID *clsid, bool isCoder2, bool isFilter, bool &encode, int &index) throw() { index = -1; - if (clsID->Data1 != CLSID_CCodec.Data1 || - clsID->Data2 != CLSID_CCodec.Data2) + if (clsid->Data1 != k_7zip_GUID_Data1 || + clsid->Data2 != k_7zip_GUID_Data2) return S_OK; + encode = true; - if (clsID->Data3 == kDecodeId) - encode = false; - else if (clsID->Data3 != kEncodeId) - return S_OK; - UInt64 id = GetUi64(clsID->Data4); + + if (clsid->Data3 == k_7zip_GUID_Data3_Decoder) encode = false; + else if (clsid->Data3 != k_7zip_GUID_Data3_Encoder) return S_OK; + + UInt64 id = GetUi64(clsid->Data4); + for (unsigned i = 0; i < g_NumCodecs; i++) { const CCodecInfo &codec = *g_Codecs[i]; - if (id != codec.Id || encode && !codec.CreateEncoder || !encode && !codec.CreateDecoder) + + if (id != codec.Id + || (encode ? !codec.CreateEncoder : !codec.CreateDecoder) + || (isFilter ? !codec.IsFilter : codec.IsFilter)) continue; - if (!isFilter && codec.IsFilter || isFilter && !codec.IsFilter || - codec.NumInStreams != 1 && !isCoder2 || codec.NumInStreams == 1 && isCoder2) + + if (codec.NumStreams == 1 ? isCoder2 : !isCoder2) return E_NOINTERFACE; + index = i; return S_OK; } + return S_OK; } -STDAPI CreateCoder2(bool encode, int index, const GUID *iid, void **outObject) +static HRESULT CreateCoderMain(unsigned index, bool encode, void **coder) { COM_TRY_BEGIN - *outObject = 0; - bool isCoder = (*iid == IID_ICompressCoder) != 0; - bool isCoder2 = (*iid == IID_ICompressCoder2) != 0; - bool isFilter = (*iid == IID_ICompressFilter) != 0; + const CCodecInfo &codec = *g_Codecs[index]; - if (!isFilter && codec.IsFilter || isFilter && !codec.IsFilter || - codec.NumInStreams != 1 && !isCoder2 || codec.NumInStreams == 1 && isCoder2) - return E_NOINTERFACE; + + void *c; if (encode) - { - if (!codec.CreateEncoder) - return CLASS_E_CLASSNOTAVAILABLE; - *outObject = codec.CreateEncoder(); - } + c = codec.CreateEncoder(); else + c = codec.CreateDecoder(); + + if (c) { - if (!codec.CreateDecoder) - return CLASS_E_CLASSNOTAVAILABLE; - *outObject = codec.CreateDecoder(); - } - if (*outObject) - { - if (isCoder) - ((ICompressCoder *)*outObject)->AddRef(); - else if (isCoder2) - ((ICompressCoder2 *)*outObject)->AddRef(); + IUnknown *unk; + if (codec.IsFilter) + unk = (IUnknown *)(ICompressFilter *)c; + else if (codec.NumStreams != 1) + unk = (IUnknown *)(ICompressCoder2 *)c; else - ((ICompressFilter *)*outObject)->AddRef(); + unk = (IUnknown *)(ICompressCoder *)c; + unk->AddRef(); + *coder = c; } return S_OK; + COM_TRY_END } +static HRESULT CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **outObject) +{ + *outObject = NULL; + + const CCodecInfo &codec = *g_Codecs[index]; + + if (encode ? !codec.CreateEncoder : !codec.CreateDecoder) + return CLASS_E_CLASSNOTAVAILABLE; + + if (codec.IsFilter) + { + if (*iid != IID_ICompressFilter) return E_NOINTERFACE; + } + else if (codec.NumStreams != 1) + { + if (*iid != IID_ICompressCoder2) return E_NOINTERFACE; + } + else + { + if (*iid != IID_ICompressCoder) return E_NOINTERFACE; + } + + return CreateCoderMain(index, encode, outObject); +} + +STDAPI CreateDecoder(UInt32 index, const GUID *iid, void **outObject) +{ + return CreateCoder2(false, index, iid, outObject); +} + +STDAPI CreateEncoder(UInt32 index, const GUID *iid, void **outObject) +{ + return CreateCoder2(true, index, iid, outObject); +} + STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject) { - COM_TRY_BEGIN - *outObject = 0; + *outObject = NULL; + + bool isFilter = false; + bool isCoder2 = false; bool isCoder = (*iid == IID_ICompressCoder) != 0; - bool isCoder2 = (*iid == IID_ICompressCoder2) != 0; - bool isFilter = (*iid == IID_ICompressFilter) != 0; - if (!isCoder && !isCoder2 && !isFilter) - return E_NOINTERFACE; + if (!isCoder) + { + isFilter = (*iid == IID_ICompressFilter) != 0; + if (!isFilter) + { + isCoder2 = (*iid == IID_ICompressCoder2) != 0; + if (!isCoder2) + return E_NOINTERFACE; + } + } + bool encode; int codecIndex; HRESULT res = FindCodecClassId(clsid, isCoder2, isFilter, encode, codecIndex); @@ -127,24 +173,9 @@ STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject) if (codecIndex < 0) return CLASS_E_CLASSNOTAVAILABLE; - 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 + return CreateCoderMain(codecIndex, encode, outObject); } - + STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value) { ::VariantClear((VARIANTARG *)value); @@ -156,24 +187,54 @@ STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value) value->vt = VT_UI8; break; case NMethodPropID::kName: - if ((value->bstrVal = ::SysAllocString(codec.Name)) != 0) - value->vt = VT_BSTR; + SetPropFromAscii(codec.Name, value); break; case NMethodPropID::kDecoder: if (codec.CreateDecoder) - return SetClassID(codec.Id, kDecodeId, value); + return MethodToClassID(k_7zip_GUID_Data3_Decoder, codec.Id, value); break; case NMethodPropID::kEncoder: if (codec.CreateEncoder) - return SetClassID(codec.Id, kEncodeId, value); + return MethodToClassID(k_7zip_GUID_Data3_Encoder, codec.Id, value); + break; + case NMethodPropID::kDecoderIsAssigned: + value->vt = VT_BOOL; + value->boolVal = BoolToVARIANT_BOOL(codec.CreateDecoder != NULL); + break; + case NMethodPropID::kEncoderIsAssigned: + value->vt = VT_BOOL; + value->boolVal = BoolToVARIANT_BOOL(codec.CreateEncoder != NULL); + break; + case NMethodPropID::kPackStreams: + if (codec.NumStreams != 1) + { + value->vt = VT_UI4; + value->ulVal = (ULONG)codec.NumStreams; + } break; - case NMethodPropID::kInStreams: - if (codec.NumInStreams != 1) + /* + case NMethodPropID::kIsFilter: + // if (codec.IsFilter) + { + value->vt = VT_BOOL; + value->boolVal = BoolToVARIANT_BOOL(codec.IsFilter); + } + break; + */ + /* + case NMethodPropID::kDecoderFlags: + { + value->vt = VT_UI4; + value->ulVal = (ULONG)codec.DecoderFlags; + } + break; + case NMethodPropID::kEncoderFlags: { value->vt = VT_UI4; - value->ulVal = (ULONG)codec.NumInStreams; + value->ulVal = (ULONG)codec.EncoderFlags; } break; + */ } return S_OK; } @@ -185,13 +246,15 @@ STDAPI GetNumberOfMethods(UINT32 *numCodecs) } -static int FindHasherClassId(const GUID *clsID) +// ---------- Hashers ---------- + +static int FindHasherClassId(const GUID *clsid) throw() { - if (clsID->Data1 != CLSID_CCodec.Data1 || - clsID->Data2 != CLSID_CCodec.Data2 || - clsID->Data3 != kHasherId) + if (clsid->Data1 != k_7zip_GUID_Data1 || + clsid->Data2 != k_7zip_GUID_Data2 || + clsid->Data3 != k_7zip_GUID_Data3_Hasher) return -1; - UInt64 id = GetUi64(clsID->Data4); + UInt64 id = GetUi64(clsid->Data4); for (unsigned i = 0; i < g_NumCodecs; i++) if (id == g_Hashers[i]->Id) return i; @@ -230,12 +293,11 @@ STDAPI GetHasherProp(UInt32 codecIndex, PROPID propID, PROPVARIANT *value) value->vt = VT_UI8; break; case NMethodPropID::kName: - if ((value->bstrVal = ::SysAllocString(codec.Name)) != 0) - value->vt = VT_BSTR; + SetPropFromAscii(codec.Name, value); break; case NMethodPropID::kEncoder: if (codec.CreateHasher) - return SetClassID(codec.Id, kHasherId, value); + return MethodToClassID(k_7zip_GUID_Data3_Hasher, codec.Id, value); break; case NMethodPropID::kDigestSize: value->ulVal = (ULONG)codec.DigestSize; diff --git a/CPP/7zip/Compress/CopyCoder.cpp b/CPP/7zip/Compress/CopyCoder.cpp index f0863202..ac6ab2e7 100644 --- a/CPP/7zip/Compress/CopyCoder.cpp +++ b/CPP/7zip/Compress/CopyCoder.cpp @@ -4,17 +4,15 @@ #include "../../../C/Alloc.h" -#include "../Common/StreamUtils.h" - #include "CopyCoder.h" namespace NCompress { -static const UInt32 kBufferSize = 1 << 17; +static const UInt32 kBufSize = 1 << 17; CCopyCoder::~CCopyCoder() { - ::MidFree(_buffer); + ::MidFree(_buf); } STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, @@ -22,35 +20,78 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) { - if (!_buffer) + if (!_buf) { - _buffer = (Byte *)::MidAlloc(kBufferSize); - if (!_buffer) + _buf = (Byte *)::MidAlloc(kBufSize); + if (!_buf) return E_OUTOFMEMORY; } TotalSize = 0; + for (;;) { - UInt32 size = kBufferSize; + UInt32 size = kBufSize; if (outSize && size > *outSize - TotalSize) size = (UInt32)(*outSize - TotalSize); - RINOK(inStream->Read(_buffer, size, &size)); if (size == 0) - break; + return S_OK; + + HRESULT readRes = inStream->Read(_buf, size, &size); + + if (size == 0) + return readRes; + if (outStream) { - RINOK(WriteStream(outStream, _buffer, size)); + UInt32 pos = 0; + do + { + UInt32 curSize = size - pos; + HRESULT res = outStream->Write(_buf + pos, curSize, &curSize); + pos += curSize; + TotalSize += curSize; + RINOK(res); + if (curSize == 0) + return E_FAIL; + } + while (pos < size); } - TotalSize += size; + else + TotalSize += size; + + RINOK(readRes); + if (progress) { RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize)); } } +} + +STDMETHODIMP CCopyCoder::SetInStream(ISequentialInStream *inStream) +{ + _inStream = inStream; + TotalSize = 0; + return S_OK; +} + +STDMETHODIMP CCopyCoder::ReleaseInStream() +{ + _inStream.Release(); return S_OK; } +STDMETHODIMP CCopyCoder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize = 0; + HRESULT res = _inStream->Read(data, size, &realProcessedSize); + TotalSize += realProcessedSize; + if (processedSize) + *processedSize = realProcessedSize; + return res; +} + STDMETHODIMP CCopyCoder::GetInStreamProcessedSize(UInt64 *value) { *value = TotalSize; diff --git a/CPP/7zip/Compress/CopyCoder.h b/CPP/7zip/Compress/CopyCoder.h index 5e0bb643..a21c0988 100644 --- a/CPP/7zip/Compress/CopyCoder.h +++ b/CPP/7zip/Compress/CopyCoder.h @@ -11,19 +11,30 @@ namespace NCompress { class CCopyCoder: public ICompressCoder, + public ICompressSetInStream, + public ISequentialInStream, public ICompressGetInStreamProcessedSize, public CMyUnknownImp { - Byte *_buffer; + Byte *_buf; + CMyComPtr<ISequentialInStream> _inStream; public: UInt64 TotalSize; - CCopyCoder(): TotalSize(0), _buffer(0) {}; + + CCopyCoder(): _buf(0), TotalSize(0) {}; ~CCopyCoder(); - MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize) + MY_UNKNOWN_IMP4( + ICompressCoder, + ICompressSetInStream, + ISequentialInStream, + ICompressGetInStreamProcessedSize) STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(ReleaseInStream)(); + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); }; diff --git a/CPP/7zip/Compress/CopyRegister.cpp b/CPP/7zip/Compress/CopyRegister.cpp index efb9b9e9..703c52ca 100644 --- a/CPP/7zip/Compress/CopyRegister.cpp +++ b/CPP/7zip/Compress/CopyRegister.cpp @@ -6,9 +6,6 @@ #include "CopyCoder.h" -static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::CCopyCoder); } +REGISTER_CODEC_CREATE(CreateCodec, NCompress::CCopyCoder()) -static CCodecInfo g_CodecInfo = -{ CreateCodec, CreateCodec, 0x00, L"Copy", 1, false }; - -REGISTER_CODEC(Copy) +REGISTER_CODEC_2(Copy, CreateCodec, CreateCodec, 0, "Copy") diff --git a/CPP/7zip/Compress/Deflate64Register.cpp b/CPP/7zip/Compress/Deflate64Register.cpp index 509e675a..4b2cf0f7 100644 --- a/CPP/7zip/Compress/Deflate64Register.cpp +++ b/CPP/7zip/Compress/Deflate64Register.cpp @@ -6,15 +6,13 @@ #include "DeflateDecoder.h" -static void *CreateCodecDeflate64() { return (void *)(ICompressCoder *)(new NCompress::NDeflate::NDecoder::CCOMCoder64); } +REGISTER_CODEC_CREATE(CreateDec, NCompress::NDeflate::NDecoder::CCOMCoder64()) + #if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY) #include "DeflateEncoder.h" -static void *CreateCodecOutDeflate64() { return (void *)(ICompressCoder *)(new NCompress::NDeflate::NEncoder::CCOMCoder64); } +REGISTER_CODEC_CREATE(CreateEnc, NCompress::NDeflate::NEncoder::CCOMCoder64()) #else -#define CreateCodecOutDeflate64 0 +#define CreateEnc NULL #endif -static CCodecInfo g_CodecInfo = - { CreateCodecDeflate64, CreateCodecOutDeflate64, 0x040109, L"Deflate64", 1, false }; - -REGISTER_CODEC(Deflate64) +REGISTER_CODEC_2(Deflate64, CreateDec, CreateEnc, 0x40109, "Deflate64") diff --git a/CPP/7zip/Compress/DeflateConst.h b/CPP/7zip/Compress/DeflateConst.h index c3ae5719..cfbbf886 100644 --- a/CPP/7zip/Compress/DeflateConst.h +++ b/CPP/7zip/Compress/DeflateConst.h @@ -6,37 +6,37 @@ namespace NCompress { namespace NDeflate { -const int kNumHuffmanBits = 15; +const unsigned kNumHuffmanBits = 15; const UInt32 kHistorySize32 = (1 << 15); const UInt32 kHistorySize64 = (1 << 16); -const UInt32 kDistTableSize32 = 30; -const UInt32 kDistTableSize64 = 32; +const unsigned kDistTableSize32 = 30; +const unsigned kDistTableSize64 = 32; -const UInt32 kNumLenSymbols32 = 256; -const UInt32 kNumLenSymbols64 = 255; // don't change it. It must be <= 255. -const UInt32 kNumLenSymbolsMax = kNumLenSymbols32; +const unsigned kNumLenSymbols32 = 256; +const unsigned kNumLenSymbols64 = 255; // don't change it. It must be <= 255. +const unsigned kNumLenSymbolsMax = kNumLenSymbols32; -const UInt32 kNumLenSlots = 29; +const unsigned kNumLenSlots = 29; -const UInt32 kFixedDistTableSize = 32; -const UInt32 kFixedLenTableSize = 31; +const unsigned kFixedDistTableSize = 32; +const unsigned kFixedLenTableSize = 31; -const UInt32 kSymbolEndOfBlock = 0x100; -const UInt32 kSymbolMatch = kSymbolEndOfBlock + 1; +const unsigned kSymbolEndOfBlock = 0x100; +const unsigned kSymbolMatch = kSymbolEndOfBlock + 1; -const UInt32 kMainTableSize = kSymbolMatch + kNumLenSlots; -const UInt32 kFixedMainTableSize = kSymbolMatch + kFixedLenTableSize; +const unsigned kMainTableSize = kSymbolMatch + kNumLenSlots; +const unsigned kFixedMainTableSize = kSymbolMatch + kFixedLenTableSize; -const UInt32 kLevelTableSize = 19; +const unsigned kLevelTableSize = 19; -const UInt32 kTableDirectLevels = 16; -const UInt32 kTableLevelRepNumber = kTableDirectLevels; -const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1; -const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1; +const unsigned kTableDirectLevels = 16; +const unsigned kTableLevelRepNumber = kTableDirectLevels; +const unsigned kTableLevel0Number = kTableLevelRepNumber + 1; +const unsigned kTableLevel0Number2 = kTableLevel0Number + 1; -const UInt32 kLevelMask = 0xF; +const unsigned kLevelMask = 0xF; const Byte kLenStart32[kFixedLenTableSize] = {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, 255, 0, 0}; @@ -58,12 +58,12 @@ const Byte kLevelDirectBits[3] = {2, 3, 7}; const Byte kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; -const UInt32 kMatchMinLen = 3; -const UInt32 kMatchMaxLen32 = kNumLenSymbols32 + kMatchMinLen - 1; //256 + 2 -const UInt32 kMatchMaxLen64 = kNumLenSymbols64 + kMatchMinLen - 1; //255 + 2 -const UInt32 kMatchMaxLen = kMatchMaxLen32; +const unsigned kMatchMinLen = 3; +const unsigned kMatchMaxLen32 = kNumLenSymbols32 + kMatchMinLen - 1; // 256 + 2 +const unsigned kMatchMaxLen64 = kNumLenSymbols64 + kMatchMinLen - 1; // 255 + 2 +const unsigned kMatchMaxLen = kMatchMaxLen32; -const int kFinalBlockFieldSize = 1; +const unsigned kFinalBlockFieldSize = 1; namespace NFinalBlockField { @@ -74,7 +74,7 @@ namespace NFinalBlockField }; } -const int kBlockTypeFieldSize = 2; +const unsigned kBlockTypeFieldSize = 2; namespace NBlockType { @@ -86,17 +86,17 @@ namespace NBlockType }; } -const int kNumLenCodesFieldSize = 5; -const int kNumDistCodesFieldSize = 5; -const int kNumLevelCodesFieldSize = 4; +const unsigned kNumLenCodesFieldSize = 5; +const unsigned kNumDistCodesFieldSize = 5; +const unsigned kNumLevelCodesFieldSize = 4; -const UInt32 kNumLitLenCodesMin = 257; -const UInt32 kNumDistCodesMin = 1; -const UInt32 kNumLevelCodesMin = 4; +const unsigned kNumLitLenCodesMin = 257; +const unsigned kNumDistCodesMin = 1; +const unsigned kNumLevelCodesMin = 4; -const int kLevelFieldSize = 3; +const unsigned kLevelFieldSize = 3; -const int kStoredBlockLengthFieldSize = 16; +const unsigned kStoredBlockLengthFieldSize = 16; struct CLevels { @@ -105,7 +105,7 @@ struct CLevels void SubClear() { - UInt32 i; + unsigned i; for (i = kNumLitLenCodesMin; i < kFixedMainTableSize; i++) litLenLevels[i] = 0; for (i = 0; i < kFixedDistTableSize; i++) @@ -114,7 +114,7 @@ struct CLevels void SetFixedLevels() { - int i = 0; + unsigned i = 0; for (; i < 144; i++) litLenLevels[i] = 8; for (; i < 256; i++) litLenLevels[i] = 9; diff --git a/CPP/7zip/Compress/DeflateDecoder.cpp b/CPP/7zip/Compress/DeflateDecoder.cpp index 5285e143..5e2d5d3e 100644 --- a/CPP/7zip/Compress/DeflateDecoder.cpp +++ b/CPP/7zip/Compress/DeflateDecoder.cpp @@ -106,7 +106,7 @@ bool CCoder::ReadTables(void) Byte levelLevels[kLevelTableSize]; for (unsigned i = 0; i < kLevelTableSize; i++) { - int position = kCodeLengthAlphabetOrder[i]; + unsigned position = kCodeLengthAlphabetOrder[i]; if (i < numLevelCodes) levelLevels[position] = (Byte)ReadBits(kLevelFieldSize); else @@ -299,7 +299,7 @@ HRESULT CCoder::CodeReal(ISequentialOutStream *outStream, finishInputStream = true; } } - if (curSize == 0) + if (!finishInputStream && curSize == 0) break; RINOK(CodeSpec(curSize, finishInputStream)); if (_remainLen == kLenIdFinished) @@ -314,12 +314,12 @@ HRESULT CCoder::CodeReal(ISequentialOutStream *outStream, if (_remainLen == kLenIdFinished && ZlibMode) { m_InBitStream.AlignToByte(); - for (int i = 0; i < 4; i++) + for (unsigned i = 0; i < 4; i++) ZlibFooter[i] = ReadAlignedByte(); } flusher.NeedFlush = false; res = Flush(); - if (res == S_OK && InputEofError()) + if (res == S_OK && _remainLen != kLenIdNeedInit && InputEofError()) return S_FALSE; DEFLATE_TRY_END(res) return res; diff --git a/CPP/7zip/Compress/DeflateEncoder.cpp b/CPP/7zip/Compress/DeflateEncoder.cpp index 392ee93d..eb012e8d 100644 --- a/CPP/7zip/Compress/DeflateEncoder.cpp +++ b/CPP/7zip/Compress/DeflateEncoder.cpp @@ -21,7 +21,7 @@ namespace NCompress { namespace NDeflate { namespace NEncoder { -static const int kNumDivPassesMax = 10; // [0, 16); ratio/speed/ram tradeoff; use big value for better compression ratio. +static const unsigned kNumDivPassesMax = 10; // [0, 16); ratio/speed/ram tradeoff; use big value for better compression ratio. static const UInt32 kNumTables = (1 << kNumDivPassesMax); static const UInt32 kFixedHuffmanCodeBlockSizeMax = (1 << 8); // [0, (1 << 32)); ratio/speed tradeoff; use big value for better compression ratio. @@ -34,8 +34,8 @@ static const UInt32 kMatchArrayLimit = kMatchArraySize - kMatchMaxLen * 4 * size static const UInt32 kBlockUncompressedSizeThreshold = kMaxUncompressedBlockSize - kMatchMaxLen - kNumOpts; -static const int kMaxCodeBitLength = 11; -static const int kMaxLevelBitLength = 7; +static const unsigned kMaxCodeBitLength = 11; +static const unsigned kMaxLevelBitLength = 7; static const Byte kNoLiteralStatPrice = 11; static const Byte kNoLenStatPrice = 11; @@ -49,17 +49,17 @@ class CFastPosInit public: CFastPosInit() { - int i; + unsigned i; for (i = 0; i < kNumLenSlots; i++) { - int c = kLenStart32[i]; - int j = 1 << kLenDirectBits32[i]; - for (int k = 0; k < j; k++, c++) + unsigned c = kLenStart32[i]; + unsigned j = 1 << kLenDirectBits32[i]; + for (unsigned k = 0; k < j; k++, c++) g_LenSlots[c] = (Byte)i; } - const int kFastSlots = 18; - int c = 0; + const unsigned kFastSlots = 18; + unsigned c = 0; for (Byte slotFast = 0; slotFast < kFastSlots; slotFast++) { UInt32 k = (1 << kDistDirectBits[slotFast]); @@ -79,10 +79,6 @@ inline UInt32 GetPosSlot(UInt32 pos) return g_FastPos[pos >> 8] + 16; } -static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } -static void SzFree(void *p, void *address) { p = p; MyFree(address); } -static ISzAlloc g_Alloc = { SzAlloc, SzFree }; - void CEncProps::Normalize() { int level = Level; @@ -183,7 +179,7 @@ HRESULT CCoder::Create() if (!m_Created) { - _lzInWindow.btMode = _btMode ? 1 : 0; + _lzInWindow.btMode = (Byte)(_btMode ? 1 : 0); _lzInWindow.numHashBytes = 3; if (!MatchFinder_Create(&_lzInWindow, m_Deflate64Mode ? kHistorySize64 : kHistorySize32, @@ -348,7 +344,7 @@ NO_INLINE UInt32 CCoder::GetOptimal(UInt32 &backRes) MovePos(lenMain - 1); return lenMain; } - m_Optimum[1].Price = m_LiteralPrices[Inline_MatchFinder_GetIndexByte(&_lzInWindow, 0 - m_AdditionalOffset)]; + m_Optimum[1].Price = m_LiteralPrices[*(Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow) - m_AdditionalOffset)]; m_Optimum[1].PosPrev = 0; m_Optimum[2].Price = kIfinityPrice; @@ -392,7 +388,7 @@ NO_INLINE UInt32 CCoder::GetOptimal(UInt32 &backRes) } } UInt32 curPrice = m_Optimum[cur].Price; - UInt32 curAnd1Price = curPrice + m_LiteralPrices[Inline_MatchFinder_GetIndexByte(&_lzInWindow, cur - m_AdditionalOffset)]; + UInt32 curAnd1Price = curPrice + m_LiteralPrices[*(Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow) + cur - m_AdditionalOffset)]; COptimal &optimum = m_Optimum[cur + 1]; if (curAnd1Price < optimum.Price) { @@ -453,21 +449,23 @@ void CTables::InitStructures() distLevels[i] = 5; } -NO_INLINE void CCoder::LevelTableDummy(const Byte *levels, int numLevels, UInt32 *freqs) +NO_INLINE void CCoder::LevelTableDummy(const Byte *levels, unsigned numLevels, UInt32 *freqs) { - int prevLen = 0xFF; - int nextLen = levels[0]; - int count = 0; - int maxCount = 7; - int minCount = 4; + unsigned prevLen = 0xFF; + unsigned nextLen = levels[0]; + unsigned count = 0; + unsigned maxCount = 7; + unsigned minCount = 4; + if (nextLen == 0) { maxCount = 138; minCount = 3; } - for (int n = 0; n < numLevels; n++) + + for (unsigned n = 0; n < numLevels; n++) { - int curLen = nextLen; + unsigned curLen = nextLen; nextLen = (n < numLevels - 1) ? levels[n + 1] : 0xFF; count++; if (count < maxCount && curLen == nextLen) @@ -510,7 +508,7 @@ NO_INLINE void CCoder::LevelTableDummy(const Byte *levels, int numLevels, UInt32 } } -NO_INLINE void CCoder::WriteBits(UInt32 value, int numBits) +NO_INLINE void CCoder::WriteBits(UInt32 value, unsigned numBits) { m_OutStream.WriteBits(value, numBits); } @@ -518,28 +516,30 @@ NO_INLINE void CCoder::WriteBits(UInt32 value, int numBits) #define WRITE_HF2(codes, lens, i) m_OutStream.WriteBits(codes[i], lens[i]) #define WRITE_HF(i) WriteBits(codes[i], lens[i]) -NO_INLINE void CCoder::LevelTableCode(const Byte *levels, int numLevels, const Byte *lens, const UInt32 *codes) +NO_INLINE void CCoder::LevelTableCode(const Byte *levels, unsigned numLevels, const Byte *lens, const UInt32 *codes) { - int prevLen = 0xFF; - int nextLen = levels[0]; - int count = 0; - int maxCount = 7; - int minCount = 4; + unsigned prevLen = 0xFF; + unsigned nextLen = levels[0]; + unsigned count = 0; + unsigned maxCount = 7; + unsigned minCount = 4; + if (nextLen == 0) { maxCount = 138; minCount = 3; } - for (int n = 0; n < numLevels; n++) + + for (unsigned n = 0; n < numLevels; n++) { - int curLen = nextLen; + unsigned curLen = nextLen; nextLen = (n < numLevels - 1) ? levels[n + 1] : 0xFF; count++; if (count < maxCount && curLen == nextLen) continue; if (count < minCount) - for (int i = 0; i < count; i++) + for (unsigned i = 0; i < count; i++) WRITE_HF(curLen); else if (curLen != 0) { @@ -644,7 +644,7 @@ NO_INLINE void CCoder::TryBlock() } else { - Byte b = Inline_MatchFinder_GetIndexByte(&_lzInWindow, 0 - m_AdditionalOffset); + Byte b = *(Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow) - m_AdditionalOffset); mainFreqs[b]++; codeValue.SetAsLiteral(); codeValue.Pos = b; @@ -719,13 +719,13 @@ NO_INLINE void CCoder::WriteBlock() WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, kSymbolEndOfBlock); } -static UInt32 GetStorePrice(UInt32 blockSize, int bitPosition) +static UInt32 GetStorePrice(UInt32 blockSize, unsigned bitPosition) { UInt32 price = 0; do { UInt32 nextBitPosition = (bitPosition + kFinalBlockFieldSize + kBlockTypeFieldSize) & 7; - int numBitsForAlign = nextBitPosition > 0 ? (8 - nextBitPosition): 0; + unsigned numBitsForAlign = nextBitPosition > 0 ? (8 - nextBitPosition): 0; UInt32 curBlockSize = (blockSize < (1 << 16)) ? blockSize : (1 << 16) - 1; price += kFinalBlockFieldSize + kBlockTypeFieldSize + numBitsForAlign + (2 + 2) * 8 + curBlockSize * 8; bitPosition = 0; @@ -754,7 +754,7 @@ void CCoder::WriteStoreBlock(UInt32 blockSize, UInt32 additionalOffset, bool fin while (blockSize != 0); } -NO_INLINE UInt32 CCoder::TryDynBlock(int tableIndex, UInt32 numPasses) +NO_INLINE UInt32 CCoder::TryDynBlock(unsigned tableIndex, UInt32 numPasses) { CTables &t = m_Tables[tableIndex]; BlockSizeRes = t.BlockSizeRes; @@ -806,7 +806,7 @@ NO_INLINE UInt32 CCoder::TryDynBlock(int tableIndex, UInt32 numPasses) m_NumLevelCodes * kLevelFieldSize + kFinalBlockFieldSize + kBlockTypeFieldSize; } -NO_INLINE UInt32 CCoder::TryFixedBlock(int tableIndex) +NO_INLINE UInt32 CCoder::TryFixedBlock(unsigned tableIndex) { CTables &t = m_Tables[tableIndex]; BlockSizeRes = t.BlockSizeRes; @@ -817,7 +817,7 @@ NO_INLINE UInt32 CCoder::TryFixedBlock(int tableIndex) return kFinalBlockFieldSize + kBlockTypeFieldSize + GetLzBlockPrice(); } -NO_INLINE UInt32 CCoder::GetBlockPrice(int tableIndex, int numDivPasses) +NO_INLINE UInt32 CCoder::GetBlockPrice(unsigned tableIndex, unsigned numDivPasses) { CTables &t = m_Tables[tableIndex]; t.StaticMode = false; @@ -864,12 +864,13 @@ NO_INLINE UInt32 CCoder::GetBlockPrice(int tableIndex, int numDivPasses) price = subPrice; } } + m_AdditionalOffset = additionalOffsetEnd; m_Pos = posTemp; return price; } -void CCoder::CodeBlock(int tableIndex, bool finalBlock) +void CCoder::CodeBlock(unsigned tableIndex, bool finalBlock) { CTables &t = m_Tables[tableIndex]; if (t.UseSubBlocks) @@ -888,8 +889,8 @@ void CCoder::CodeBlock(int tableIndex, bool finalBlock) { WriteBits(NBlockType::kFixedHuffman, kBlockTypeFieldSize); TryFixedBlock(tableIndex); - int i; - const int kMaxStaticHuffLen = 9; + unsigned i; + const unsigned kMaxStaticHuffLen = 9; for (i = 0; i < kFixedMainTableSize; i++) mainFreqs[i] = (UInt32)1 << (kMaxStaticHuffLen - m_NewLevels.litLenLevels[i]); for (i = 0; i < kFixedDistTableSize; i++) diff --git a/CPP/7zip/Compress/DeflateEncoder.h b/CPP/7zip/Compress/DeflateEncoder.h index d8e88f89..62423a34 100644 --- a/CPP/7zip/Compress/DeflateEncoder.h +++ b/CPP/7zip/Compress/DeflateEncoder.h @@ -91,8 +91,8 @@ public: UInt32 m_Pos; - int m_NumPasses; - int m_NumDivPasses; + unsigned m_NumPasses; + unsigned m_NumDivPasses; bool m_CheckStatic; bool m_IsMultiPass; UInt32 m_ValueBlockSize; @@ -106,8 +106,8 @@ public: bool m_Deflate64Mode; Byte m_LevelLevels[kLevelTableSize]; - int m_NumLitLenLevels; - int m_NumDistLevels; + unsigned m_NumLitLenLevels; + unsigned m_NumDistLevels; UInt32 m_NumLevelCodes; UInt32 m_ValueIndex; @@ -142,17 +142,17 @@ public: UInt32 GetOptimal(UInt32 &backRes); UInt32 GetOptimalFast(UInt32 &backRes); - void LevelTableDummy(const Byte *levels, int numLevels, UInt32 *freqs); + void LevelTableDummy(const Byte *levels, unsigned numLevels, UInt32 *freqs); - void WriteBits(UInt32 value, int numBits); - void LevelTableCode(const Byte *levels, int numLevels, const Byte *lens, const UInt32 *codes); + void WriteBits(UInt32 value, unsigned numBits); + void LevelTableCode(const Byte *levels, unsigned numLevels, const Byte *lens, const UInt32 *codes); void MakeTables(unsigned maxHuffLen); UInt32 GetLzBlockPrice() const; void TryBlock(); - UInt32 TryDynBlock(int tableIndex, UInt32 numPasses); + UInt32 TryDynBlock(unsigned tableIndex, UInt32 numPasses); - UInt32 TryFixedBlock(int tableIndex); + UInt32 TryFixedBlock(unsigned tableIndex); void SetPrices(const CLevels &levels); void WriteBlock(); @@ -165,8 +165,8 @@ public: void WriteBlockData(bool writeMode, bool finalBlock); - UInt32 GetBlockPrice(int tableIndex, int numDivPasses); - void CodeBlock(int tableIndex, bool finalBlock); + UInt32 GetBlockPrice(unsigned tableIndex, unsigned numDivPasses); + void CodeBlock(unsigned tableIndex, bool finalBlock); void SetProps(const CEncProps *props2); public: diff --git a/CPP/7zip/Compress/DeflateRegister.cpp b/CPP/7zip/Compress/DeflateRegister.cpp index 45f55219..32221fcc 100644 --- a/CPP/7zip/Compress/DeflateRegister.cpp +++ b/CPP/7zip/Compress/DeflateRegister.cpp @@ -6,16 +6,13 @@ #include "DeflateDecoder.h" -static void *CreateCodecDeflate() { return (void *)(ICompressCoder *)(new NCompress::NDeflate::NDecoder::CCOMCoder); } +REGISTER_CODEC_CREATE(CreateDec, NCompress::NDeflate::NDecoder::CCOMCoder) #if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY) #include "DeflateEncoder.h" -static void *CreateCodecOutDeflate() { return (void *)(ICompressCoder *)(new NCompress::NDeflate::NEncoder::CCOMCoder); } +REGISTER_CODEC_CREATE(CreateEnc, NCompress::NDeflate::NEncoder::CCOMCoder) #else -#define CreateCodecOutDeflate 0 +#define CreateEnc NULL #endif -static CCodecInfo g_CodecInfo = - { CreateCodecDeflate, CreateCodecOutDeflate, 0x040108, L"Deflate", 1, false }; - -REGISTER_CODEC(Deflate) +REGISTER_CODEC_2(Deflate, CreateDec, CreateEnc, 0x40108, "Deflate") diff --git a/CPP/7zip/Compress/DeltaFilter.cpp b/CPP/7zip/Compress/DeltaFilter.cpp index d8378a60..d90f62f5 100644 --- a/CPP/7zip/Compress/DeltaFilter.cpp +++ b/CPP/7zip/Compress/DeltaFilter.cpp @@ -4,18 +4,24 @@ #include "../../../C/Delta.h" -#include "../Common/RegisterCodec.h" +#include "../../Common/MyCom.h" + +#include "../ICoder.h" -#include "BranchCoder.h" +#include "../Common/RegisterCodec.h" struct CDelta { unsigned _delta; Byte _state[DELTA_STATE_SIZE]; + CDelta(): _delta(1) {} void DeltaInit() { Delta_Init(_state); } }; + +#ifndef EXTRACT_ONLY + class CDeltaEncoder: public ICompressFilter, public ICompressSetCoderProperties, @@ -25,25 +31,11 @@ class CDeltaEncoder: { public: MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties) - STDMETHOD(Init)(); - STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + INTERFACE_ICompressFilter(;) STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); }; -class CDeltaDecoder: - public ICompressFilter, - public ICompressSetDecoderProperties2, - CDelta, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) - STDMETHOD(Init)(); - STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); -}; - STDMETHODIMP CDeltaEncoder::Init() { DeltaInit(); @@ -89,6 +81,21 @@ STDMETHODIMP CDeltaEncoder::WriteCoderProperties(ISequentialOutStream *outStream return outStream->Write(&prop, 1, NULL); } +#endif + + +class CDeltaDecoder: + public ICompressFilter, + public ICompressSetDecoderProperties2, + CDelta, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) + INTERFACE_ICompressFilter(;) + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); +}; + STDMETHODIMP CDeltaDecoder::Init() { DeltaInit(); @@ -109,17 +116,8 @@ STDMETHODIMP CDeltaDecoder::SetDecoderProperties2(const Byte *props, UInt32 size return S_OK; } -#define CREATE_CODEC(x) \ - static void *CreateCodec ## x() { return (void *)(ICompressFilter *)(new C ## x ## Decoder); } \ - static void *CreateCodec ## x ## Out() { return (void *)(ICompressFilter *)(new C ## x ## Encoder); } - -CREATE_CODEC(Delta) - -#define METHOD_ITEM(x, id, name) { CreateCodec ## x, CreateCodec ## x ## Out, id, name, 1, true } - -static CCodecInfo g_CodecsInfo[] = -{ - METHOD_ITEM(Delta, 3, L"Delta") -}; -REGISTER_CODECS(Delta) +REGISTER_FILTER_E(Delta, + CDeltaDecoder(), + CDeltaEncoder(), + 3, "Delta") diff --git a/CPP/7zip/Compress/DllExports2Compress.cpp b/CPP/7zip/Compress/DllExports2Compress.cpp index 286ef08b..a6ff6905 100644 --- a/CPP/7zip/Compress/DllExports2Compress.cpp +++ b/CPP/7zip/Compress/DllExports2Compress.cpp @@ -1,4 +1,4 @@ -// DllExports.cpp +// DllExports2Compress.cpp #include "StdAfx.h" @@ -20,11 +20,6 @@ BOOL WINAPI DllMain( return TRUE; } -static const UInt16 kDecodeId = 0x2790; - -DEFINE_GUID(CLSID_CCodec, -0x23170F69, 0x40C1, kDecodeId, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject); STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) diff --git a/CPP/7zip/Compress/DllExportsCompress.cpp b/CPP/7zip/Compress/DllExportsCompress.cpp index be429277..c58d2d5e 100644 --- a/CPP/7zip/Compress/DllExportsCompress.cpp +++ b/CPP/7zip/Compress/DllExportsCompress.cpp @@ -40,11 +40,6 @@ BOOL WINAPI DllMain( } #endif -static const UInt16 kDecodeId = 0x2790; - -DEFINE_GUID(CLSID_CCodec, -0x23170F69, 0x40C1, kDecodeId, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject); STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) diff --git a/CPP/7zip/Compress/HuffmanDecoder.h b/CPP/7zip/Compress/HuffmanDecoder.h index 21f96f0d..6faf8005 100644 --- a/CPP/7zip/Compress/HuffmanDecoder.h +++ b/CPP/7zip/Compress/HuffmanDecoder.h @@ -8,39 +8,42 @@ namespace NCompress { namespace NHuffman { -const int kNumTableBits = 9; +const unsigned kNumTableBits = 9; -template <int kNumBitsMax, UInt32 m_NumSymbols> +template <unsigned kNumBitsMax, UInt32 m_NumSymbols> class CDecoder { UInt32 m_Limits[kNumBitsMax + 1]; // m_Limits[i] = value limit for symbols with length = i UInt32 m_Positions[kNumBitsMax + 1]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i UInt32 m_Symbols[m_NumSymbols]; - Byte m_Lengths[1 << kNumTableBits]; // Table oh length for short codes. + Byte m_Lengths[1 << kNumTableBits]; // Table of length for short codes public: - - bool SetCodeLengths(const Byte *codeLengths) + + bool SetCodeLengths(const Byte *lens) { - int lenCounts[kNumBitsMax + 1]; + unsigned lenCounts[kNumBitsMax + 1]; UInt32 tmpPositions[kNumBitsMax + 1]; - int i; + unsigned i; for (i = 1; i <= kNumBitsMax; i++) lenCounts[i] = 0; UInt32 symbol; + for (symbol = 0; symbol < m_NumSymbols; symbol++) { - int len = codeLengths[symbol]; + unsigned len = lens[symbol]; if (len > kNumBitsMax) return false; lenCounts[len]++; m_Symbols[symbol] = 0xFFFFFFFF; } + lenCounts[0] = 0; m_Positions[0] = m_Limits[0] = 0; UInt32 startPos = 0; UInt32 index = 0; const UInt32 kMaxValue = (1 << kNumBitsMax); + for (i = 1; i <= kNumBitsMax; i++) { startPos += lenCounts[i] << (kNumBitsMax - i); @@ -56,19 +59,21 @@ public: m_Lengths[index] = (Byte)i; } } + for (symbol = 0; symbol < m_NumSymbols; symbol++) { - int len = codeLengths[symbol]; + unsigned len = lens[symbol]; if (len != 0) m_Symbols[tmpPositions[len]++] = symbol; } + return true; } template <class TBitDecoder> UInt32 DecodeSymbol(TBitDecoder *bitStream) { - int numBits; + unsigned numBits; UInt32 value = bitStream->GetValue(kNumBitsMax); if (value < m_Limits[kNumTableBits]) numBits = m_Lengths[value >> (kNumBitsMax - kNumTableBits)]; diff --git a/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp b/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp index 2170326e..d385d7b1 100644 --- a/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp +++ b/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp @@ -21,9 +21,9 @@ CDecoder::~CDecoder() bool CDecoder::SetCodeLengths(const Byte *codeLengths) { - // int lenCounts[kNumBitsInLongestCode + 1], tmpPositions[kNumBitsInLongestCode + 1]; - int lenCounts[kNumBitsInLongestCode + 2], tmpPositions[kNumBitsInLongestCode + 1]; - int i; + // unsigned lenCounts[kNumBitsInLongestCode + 1], tmpPositions[kNumBitsInLongestCode + 1]; + unsigned lenCounts[kNumBitsInLongestCode + 2], tmpPositions[kNumBitsInLongestCode + 1]; + unsigned i; for (i = 0; i <= kNumBitsInLongestCode; i++) lenCounts[i] = 0; UInt32 symbolIndex; @@ -67,7 +67,7 @@ UInt32 CDecoder::DecodeSymbol(CInBit *inStream) { UInt32 numBits = 0; UInt32 value = inStream->GetValue(kNumBitsInLongestCode); - int i; + unsigned 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..691a8e93 100644 --- a/CPP/7zip/Compress/ImplodeHuffmanDecoder.h +++ b/CPP/7zip/Compress/ImplodeHuffmanDecoder.h @@ -11,7 +11,7 @@ namespace NCompress { namespace NImplode { namespace NHuffman { -const int kNumBitsInLongestCode = 16; +const unsigned kNumBitsInLongestCode = 16; typedef NBitl::CDecoder<CInBuffer> CInBit; diff --git a/CPP/7zip/Compress/LzOutWindow.h b/CPP/7zip/Compress/LzOutWindow.h index 507aa7f4..5591744d 100644 --- a/CPP/7zip/Compress/LzOutWindow.h +++ b/CPP/7zip/Compress/LzOutWindow.h @@ -35,10 +35,13 @@ public: } else do { + UInt32 pos2; if (pos == _bufSize) pos = 0; - _buf[_pos++] = _buf[pos++]; - if (_pos == _limitPos) + pos2 = _pos; + _buf[pos2++] = _buf[pos++]; + _pos = pos2; + if (pos2 == _limitPos) FlushWithCheck(); } while (--len != 0); @@ -47,15 +50,17 @@ public: void PutByte(Byte b) { - _buf[_pos++] = b; - if (_pos == _limitPos) + UInt32 pos = _pos; + _buf[pos++] = b; + _pos = pos; + if (pos == _limitPos) FlushWithCheck(); } Byte GetByte(UInt32 distance) const { UInt32 pos = _pos - distance - 1; - if (pos >= _bufSize) + if (distance >= _pos) pos += _bufSize; return _buf[pos]; } diff --git a/CPP/7zip/Compress/LzhDecoder.cpp b/CPP/7zip/Compress/LzhDecoder.cpp index ad6e873a..bf4a0b68 100644 --- a/CPP/7zip/Compress/LzhDecoder.cpp +++ b/CPP/7zip/Compress/LzhDecoder.cpp @@ -8,208 +8,240 @@ namespace NCompress{ namespace NLzh { namespace NDecoder { -static const UInt32 kHistorySize = (1 << 16); +static const UInt32 kWindowSizeMin = 1 << 16; -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); } - -HRESULT CCoder::ReadLevelTable() +static bool CheckCodeLens(const Byte *lens, unsigned num) { - int n = ReadBits(kNumLevelBits); - if (n == 0) - { - m_LevelHuffman.Symbol = ReadBits(kNumLevelBits); - if (m_LevelHuffman.Symbol >= kNumLevelSymbols) - return S_FALSE; - } - else + UInt32 sum = 0; + for (unsigned i = 0; i < num; i++) { - if (n > kNumLevelSymbols) - return S_FALSE; - m_LevelHuffman.Symbol = -1; - Byte lens[kNumLevelSymbols]; - int i = 0; - while (i < n) - { - int c = m_InBitStream.ReadBits(3); - if (c == 7) - while (ReadBits(1)) - if (c++ > kMaxHuffmanLen) - return S_FALSE; - lens[i++] = (Byte)c; - if (i == kNumSpecLevelSymbols) - { - c = ReadBits(2); - while (--c >= 0) - lens[i++] = 0; - } - } - while (i < kNumLevelSymbols) - lens[i++] = 0; - m_LevelHuffman.SetCodeLengths(lens); + unsigned len = lens[i]; + if (len != 0) + sum += ((UInt32)1 << (NUM_CODE_BITS - len)); } - return S_OK; + return sum == ((UInt32)1 << NUM_CODE_BITS); } -HRESULT CCoder::ReadPTable(int numBits) +bool CCoder::ReadTP(unsigned num, unsigned numBits, int spec) { - int n = ReadBits(numBits); + _symbolT = -1; + + UInt32 n = _inBitStream.ReadBits(numBits); if (n == 0) { - m_PHuffmanDecoder.Symbol = ReadBits(numBits); - if (m_PHuffmanDecoder.Symbol >= kNumDistanceSymbols) - return S_FALSE; + _symbolT = _inBitStream.ReadBits(numBits); + return ((unsigned)_symbolT < num); } - else + + if (n > num) + return false; + { - if (n > kNumDistanceSymbols) - return S_FALSE; - m_PHuffmanDecoder.Symbol = -1; - Byte lens[kNumDistanceSymbols]; - int i = 0; - while (i < n) + Byte lens[NPT]; + unsigned i; + for (i = 0; i < NPT; i++) + lens[i] = 0; + + i = 0; + + do { - int c = m_InBitStream.ReadBits(3); + UInt32 val = _inBitStream.GetValue(16); + unsigned c = val >> 13; + if (c == 7) - while (ReadBits(1)) + { + UInt32 mask = 1 << 12; + while (mask & val) { - if (c > kMaxHuffmanLen) - return S_FALSE; + mask >>= 1; c++; } + if (c > 16) + return false; + } + + _inBitStream.MovePos(c < 7 ? 3 : c - 3); lens[i++] = (Byte)c; + + if (i == (unsigned)spec) + i += _inBitStream.ReadBits(2); } - while (i < kNumDistanceSymbols) - lens[i++] = 0; - m_PHuffmanDecoder.SetCodeLengths(lens); + while (i < n); + + if (!CheckCodeLens(lens, NPT)) + return false; + return _decoderT.SetCodeLengths(lens); } - return S_OK; } -HRESULT CCoder::ReadCTable() +static const unsigned NUM_C_BITS = 9; + +bool CCoder::ReadC() { - int n = ReadBits(kNumCBits); + _symbolC = -1; + + unsigned n = _inBitStream.ReadBits(NUM_C_BITS); + if (n == 0) { - m_CHuffmanDecoder.Symbol = ReadBits(kNumCBits); - if (m_CHuffmanDecoder.Symbol >= kNumCSymbols) - return S_FALSE; + _symbolC = _inBitStream.ReadBits(NUM_C_BITS); + return ((unsigned)_symbolC < NC); } - else + + if (n > NC) + return false; + { - if (n > kNumCSymbols) - return S_FALSE; - m_CHuffmanDecoder.Symbol = -1; - Byte lens[kNumCSymbols]; - int i = 0; - while (i < n) + Byte lens[NC]; + + unsigned i = 0; + + do { - int c = m_LevelHuffman.Decode(&m_InBitStream); - if (c < kNumSpecLevelSymbols) + UInt32 c = (unsigned)_symbolT; + if (_symbolT < 0) + c = _decoderT.DecodeSymbol(&_inBitStream); + + if (c <= 2) { if (c == 0) c = 1; else if (c == 1) - c = ReadBits(4) + 3; + c = _inBitStream.ReadBits(4) + 3; else - c = ReadBits(kNumCBits) + 20; - while (--c >= 0) - { - if (i > kNumCSymbols) - return S_FALSE; + c = _inBitStream.ReadBits(NUM_C_BITS) + 20; + + if (i + c > n) + return false; + + do lens[i++] = 0; - } + while (--c); } else lens[i++] = (Byte)(c - 2); } - while (i < kNumCSymbols) + while (i < n); + + while (i < NC) lens[i++] = 0; - m_CHuffmanDecoder.SetCodeLengths(lens); + + if (!CheckCodeLens(lens, NC)) + return false; + return _decoderC.SetCodeLengths(lens); } - return S_OK; } -STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize, - ICompressProgressInfo *progress) +HRESULT CCoder::CodeReal(UInt64 rem, ICompressProgressInfo *progress) { - if (outSize == NULL) - return E_INVALIDARG; - - if (!m_OutWindowStream.Create(kHistorySize)) - return E_OUTOFMEMORY; - if (!m_InBitStream.Create(1 << 20)) - return E_OUTOFMEMORY; - - UInt64 pos = 0; - m_OutWindowStream.SetStream(outStream); - m_OutWindowStream.Init(false); - m_InBitStream.SetStream(inStream); - m_InBitStream.Init(); - - CCoderReleaser coderReleaser(this); - - int pbit; - if (m_NumDictBits <= 13) - pbit = 4; - else - pbit = 5; + unsigned pbit = (DictSize <= (1 << 14) ? 4 : 5); UInt32 blockSize = 0; - while (pos < *outSize) + while (rem != 0) { - // for (i = 0; i < dictSize; i++) dtext[i] = 0x20; - if (blockSize == 0) { - if (progress != NULL) + if (_inBitStream.ExtraBitsWereRead()) + return S_FALSE; + + if (progress) { - UInt64 packSize = m_InBitStream.GetProcessedSize(); + UInt64 packSize = _inBitStream.GetProcessedSize(); + UInt64 pos = _outWindow.GetProcessedSize(); RINOK(progress->SetRatioInfo(&packSize, &pos)); } - blockSize = ReadBits(kBlockSizeBits); - ReadLevelTable(); - ReadCTable(); - RINOK(ReadPTable(pbit)); + + blockSize = _inBitStream.ReadBits(16); + if (blockSize == 0) + return S_FALSE; + + if (!ReadTP(NT, 5, 3)) + return S_FALSE; + if (!ReadC()) + return S_FALSE; + if (!ReadTP(NP, pbit, -1)) + return S_FALSE; } + blockSize--; - UInt32 c = m_CHuffmanDecoder.Decode(&m_InBitStream); - if (c < 256) + + UInt32 number = (unsigned)_symbolC; + if (_symbolC < 0) + number = _decoderC.DecodeSymbol(&_inBitStream); + + if (number < 256) { - m_OutWindowStream.PutByte((Byte)c); - pos++; + _outWindow.PutByte((Byte)number); + rem--; } - else if (c >= kNumCSymbols) - return S_FALSE; else { - // offset = (interface->method == LARC_METHOD_NUM) ? 0x100 - 2 : 0x100 - 3; - UInt32 len = c - 256 + kMinMatch; - UInt32 distance = m_PHuffmanDecoder.Decode(&m_InBitStream); - if (distance != 0) - distance = (1 << (distance - 1)) + ReadBits(distance - 1); - if (distance >= pos) + UInt32 len = number - 256 + kMatchMinLen; + + UInt32 dist = (unsigned)_symbolT; + if (_symbolT < 0) + dist = _decoderT.DecodeSymbol(&_inBitStream); + + if (dist > 1) + { + dist--; + dist = ((UInt32)1 << dist) + _inBitStream.ReadBits((unsigned)dist); + } + + if (dist >= DictSize) return S_FALSE; - if (pos + len > *outSize) - len = (UInt32)(*outSize - pos); - pos += len; - m_OutWindowStream.CopyBlock(distance, len); + + if (len > rem) + len = (UInt32)rem; + + if (!_outWindow.CopyBlock(dist, len)) + return S_FALSE; + rem -= len; } } - coderReleaser.NeedFlush = false; - return m_OutWindowStream.Flush(); + + if (FinishMode) + { + if (blockSize != 0) + return S_FALSE; + if (_inBitStream.ReadAlignBits() != 0) + return S_FALSE; + } + + if (_inBitStream.ExtraBitsWereRead()) + return S_FALSE; + + return S_OK; } -STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress) + +STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) { - try { return CodeReal(inStream, outStream, inSize, outSize, progress);} + try + { + if (!outSize) + return E_INVALIDARG; + + if (!_outWindow.Create(DictSize > kWindowSizeMin ? DictSize : kWindowSizeMin)) + return E_OUTOFMEMORY; + if (!_inBitStream.Create(1 << 17)) + return E_OUTOFMEMORY; + + _outWindow.SetStream(outStream); + _outWindow.Init(false); + _inBitStream.SetStream(inStream); + _inBitStream.Init(); + + CCoderReleaser coderReleaser(this); + + RINOK(CodeReal(*outSize, progress)); + + coderReleaser.Disable(); + return _outWindow.Flush(); + } catch(const CInBufferException &e) { return e.ErrorCode; } catch(const CLzOutWindowException &e) { return e.ErrorCode; } catch(...) { return S_FALSE; } diff --git a/CPP/7zip/Compress/LzhDecoder.h b/CPP/7zip/Compress/LzhDecoder.h index a0a7b244..5e13d823 100644 --- a/CPP/7zip/Compress/LzhDecoder.h +++ b/CPP/7zip/Compress/LzhDecoder.h @@ -17,89 +17,56 @@ namespace NCompress { namespace NLzh { namespace NDecoder { -const int kMaxHuffmanLen = 16; // Check it - -const int kNumSpecLevelSymbols = 3; -const int kNumLevelSymbols = kNumSpecLevelSymbols + kMaxHuffmanLen; - -const int kDictBitsMax = 16; -const int kNumDistanceSymbols = kDictBitsMax + 1; - -const int kMaxMatch = 256; -const int kMinMatch = 3; -const int kNumCSymbols = 256 + kMaxMatch + 2 - kMinMatch; - -template <UInt32 m_NumSymbols> -class CHuffmanDecoder:public NCompress::NHuffman::CDecoder<kMaxHuffmanLen, m_NumSymbols> -{ -public: - int Symbol; - template <class TBitDecoder> - UInt32 Decode(TBitDecoder *bitStream) - { - if (Symbol >= 0) - return (UInt32)Symbol; - return this->DecodeSymbol(bitStream); - } -}; - -class CCoder : +const unsigned kMatchMinLen = 3; +const unsigned kMatchMaxLen = 256; +const unsigned NC = (256 + kMatchMaxLen - kMatchMinLen + 1); +const unsigned NUM_CODE_BITS = 16; +const unsigned NUM_DIC_BITS_MAX = 25; +const unsigned NT = (NUM_CODE_BITS + 3); +const unsigned NP = (NUM_DIC_BITS_MAX + 1); +const unsigned NPT = NP; // Max(NT, NP) + +class CCoder: public ICompressCoder, public CMyUnknownImp { - CLzOutWindow m_OutWindowStream; - NBitm::CDecoder<CInBuffer> m_InBitStream; - - int m_NumDictBits; + CLzOutWindow _outWindow; + NBitm::CDecoder<CInBuffer> _inBitStream; - CHuffmanDecoder<kNumLevelSymbols> m_LevelHuffman; - CHuffmanDecoder<kNumDistanceSymbols> m_PHuffmanDecoder; - CHuffmanDecoder<kNumCSymbols> m_CHuffmanDecoder; + int _symbolT; + int _symbolC; - /* - void ReleaseStreams() - { - m_OutWindowStream.ReleaseStream(); - } - */ + NHuffman::CDecoder<NUM_CODE_BITS, NPT> _decoderT; + NHuffman::CDecoder<NUM_CODE_BITS, NC> _decoderC; class CCoderReleaser { - CCoder *m_Coder; + CCoder *_coder; public: - bool NeedFlush; - CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {} - ~CCoderReleaser() - { - if (NeedFlush) - m_Coder->m_OutWindowStream.Flush(); - // m_Coder->ReleaseStreams(); - } + CCoderReleaser(CCoder *coder): _coder(coder) {} + void Disable() { _coder = NULL; } + ~CCoderReleaser() { if (_coder) _coder->_outWindow.Flush(); } }; friend class CCoderReleaser; - void MakeTable(int nchar, Byte *bitlen, int tablebits, - UInt32 *table, int tablesize); - - UInt32 ReadBits(int numBits); - HRESULT ReadLevelTable(); - HRESULT ReadPTable(int numBits); - HRESULT ReadCTable(); + bool ReadTP(unsigned num, unsigned numBits, int spec); + bool ReadC(); + HRESULT CodeReal(UInt64 outSize, ICompressProgressInfo *progress); public: - MY_UNKNOWN_IMP - STDMETHOD(CodeReal)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress); + UInt32 DictSize; + bool FinishMode; + + STDMETHOD(Code)(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); + void SetDictSize(unsigned dictSize) { DictSize = dictSize; } + + CCoder(): DictSize(1 << 16), FinishMode(false) {} - void SetDictionary(int numDictBits) { m_NumDictBits = numDictBits; } - CCoder(): m_NumDictBits(0) {} + UInt64 GetInputProcessedSize() const { return _inBitStream.GetProcessedSize(); } }; }}} diff --git a/CPP/7zip/Compress/Lzma2Decoder.cpp b/CPP/7zip/Compress/Lzma2Decoder.cpp index 322015e2..05b136a7 100644 --- a/CPP/7zip/Compress/Lzma2Decoder.cpp +++ b/CPP/7zip/Compress/Lzma2Decoder.cpp @@ -24,32 +24,40 @@ static HRESULT SResToHRESULT(SRes res) namespace NCompress { namespace NLzma2 { -static const UInt32 kInBufSize = 1 << 20; - -CDecoder::CDecoder(): _inBuf(0), _outSizeDefined(false) +CDecoder::CDecoder(): + _inBuf(NULL), + _inBufSize(0), + _inBufSizeNew(1 << 20), + _outStepSize(1 << 22), + _outSizeDefined(false), + _finishMode(false) { Lzma2Dec_Construct(&_state); } -static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } -static void SzFree(void *p, void *address) { p = p; MyFree(address); } -static ISzAlloc g_Alloc = { SzAlloc, SzFree }; +STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSizeNew = size; return S_OK; } +STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outStepSize = size; return S_OK; } CDecoder::~CDecoder() { Lzma2Dec_Free(&_state, &g_Alloc); - MyFree(_inBuf); + MidFree(_inBuf); } STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size) { - if (size != 1) return SZ_ERROR_UNSUPPORTED; + if (size != 1) + return E_NOTIMPL; + RINOK(SResToHRESULT(Lzma2Dec_Allocate(&_state, prop[0], &g_Alloc))); - if (_inBuf == 0) + if (!_inBuf || _inBufSize != _inBufSizeNew) { - _inBuf = (Byte *)MyAlloc(kInBufSize); - if (_inBuf == 0) + MidFree(_inBuf); + _inBufSize = 0; + _inBuf = (Byte *)MidAlloc(_inBufSizeNew); + if (!_inBuf) return E_OUTOFMEMORY; + _inBufSize = _inBufSizeNew; } return S_OK; @@ -62,6 +70,7 @@ STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; } STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) { _outSizeDefined = (outSize != NULL); + _outSize = 0; if (_outSizeDefined) _outSize = *outSize; @@ -72,39 +81,55 @@ STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) return S_OK; } +STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode) +{ + _finishMode = (finishMode != 0); + return S_OK; +} + STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 * /* inSize */, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { - if (_inBuf == 0) + if (!_inBuf) return S_FALSE; SetOutStreamSize(outSize); + UInt32 step = _outStepSize; + const UInt32 kOutStepSize_Min = 1 << 12; + if (step < kOutStepSize_Min) + step = kOutStepSize_Min; + + SizeT wrPos = _state.decoder.dicPos; + + SizeT next = (_state.decoder.dicBufSize - _state.decoder.dicPos < step) ? + _state.decoder.dicBufSize : + _state.decoder.dicPos + step; + + HRESULT hres = S_OK; + for (;;) { if (_inPos == _inSize) { _inPos = _inSize = 0; - RINOK(inStream->Read(_inBuf, kInBufSize, &_inSize)); + hres = inStream->Read(_inBuf, _inBufSize, &_inSize); + if (hres != S_OK) + break; } SizeT dicPos = _state.decoder.dicPos; - SizeT curSize = _state.decoder.dicBufSize - dicPos; - const UInt32 kStepSize = ((UInt32)1 << 22); - if (curSize > kStepSize) - curSize = (SizeT)kStepSize; - + SizeT curSize = next - dicPos; + ELzmaFinishMode finishMode = LZMA_FINISH_ANY; if (_outSizeDefined) { const UInt64 rem = _outSize - _outSizeProcessed; - if (rem < curSize) + if (curSize >= rem) { curSize = (SizeT)rem; - /* - // finishMode = LZMA_FINISH_END; - we can't use LZMA_FINISH_END here to allow partial decoding - */ + if (_finishMode) + finishMode = LZMA_FINISH_END; } } @@ -117,71 +142,123 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, SizeT outSizeProcessed = _state.decoder.dicPos - dicPos; _outSizeProcessed += outSizeProcessed; - bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0); - bool stopDecoding = (_outSizeDefined && _outSizeProcessed >= _outSize); + bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0 + || status == LZMA_STATUS_FINISHED_WITH_MARK); + bool outFinished = (_outSizeDefined && _outSizeProcessed >= _outSize); - if (res != 0 || _state.decoder.dicPos == _state.decoder.dicBufSize || finished || stopDecoding) + if (res != 0 + || _state.decoder.dicPos >= next + || finished + || outFinished) { - HRESULT res2 = WriteStream(outStream, _state.decoder.dic, _state.decoder.dicPos); + HRESULT res2 = WriteStream(outStream, _state.decoder.dic + wrPos, _state.decoder.dicPos - wrPos); + + if (_state.decoder.dicPos == _state.decoder.dicBufSize) + _state.decoder.dicPos = 0; + + wrPos = _state.decoder.dicPos; + + next = (_state.decoder.dicBufSize - _state.decoder.dicPos < step) ? + _state.decoder.dicBufSize : + _state.decoder.dicPos + step; + if (res != 0) return S_FALSE; RINOK(res2); - if (stopDecoding) - return S_OK; + if (finished) - return (status == LZMA_STATUS_FINISHED_WITH_MARK ? S_OK : S_FALSE); - } - if (_state.decoder.dicPos == _state.decoder.dicBufSize) - _state.decoder.dicPos = 0; + { + if (status == LZMA_STATUS_FINISHED_WITH_MARK) + { + if (_finishMode && inSize && *inSize != _inSizeProcessed) + return S_FALSE; + if (finishMode == LZMA_FINISH_END && !outFinished) + return S_FALSE; + return S_OK; + } + return (finishMode == LZMA_FINISH_END) ? S_FALSE : S_OK; + } - if (progress != NULL) + if (outFinished && finishMode == LZMA_FINISH_ANY) + return S_OK; + } + + if (progress) { RINOK(progress->SetRatioInfo(&_inSizeProcessed, &_outSizeProcessed)); } } + + HRESULT res2 = WriteStream(outStream, _state.decoder.dic + wrPos, _state.decoder.dicPos - wrPos); + if (hres != S_OK) + return hres; + return res2; } #ifndef NO_READ_FROM_CODER STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) { + UInt32 totalProcessed = 0; + if (processedSize) *processedSize = 0; - do + + for (;;) { if (_inPos == _inSize) { _inPos = _inSize = 0; - RINOK(_inStream->Read(_inBuf, kInBufSize, &_inSize)); + RINOK(_inStream->Read(_inBuf, _inBufSize, &_inSize)); } { - SizeT inProcessed = _inSize - _inPos; - + ELzmaFinishMode finishMode = LZMA_FINISH_ANY; if (_outSizeDefined) { const UInt64 rem = _outSize - _outSizeProcessed; - if (rem < size) + if (rem <= size) + { size = (UInt32)rem; + if (_finishMode) + finishMode = LZMA_FINISH_END; + } } SizeT outProcessed = size; + SizeT inProcessed = _inSize - _inPos; + ELzmaStatus status; SRes res = Lzma2Dec_DecodeToBuf(&_state, (Byte *)data, &outProcessed, - _inBuf + _inPos, &inProcessed, LZMA_FINISH_ANY, &status); + _inBuf + _inPos, &inProcessed, finishMode, &status); + _inPos += (UInt32)inProcessed; _inSizeProcessed += inProcessed; _outSizeProcessed += outProcessed; size -= (UInt32)outProcessed; data = (Byte *)data + outProcessed; + + totalProcessed += (UInt32)outProcessed; if (processedSize) - *processedSize += (UInt32)outProcessed; - RINOK(SResToHRESULT(res)); + *processedSize = totalProcessed; + + if (res != SZ_OK) + { + if (totalProcessed != 0) + return S_OK; + return SResToHRESULT(res); + } + if (inProcessed == 0 && outProcessed == 0) return S_OK; + if (status == LZMA_STATUS_FINISHED_WITH_MARK) + return S_OK; + if (outProcessed != 0) + { + if (finishMode != LZMA_FINISH_END || _outSize != _outSizeProcessed) + return S_OK; + } } } - while (size != 0); - return S_OK; } #endif diff --git a/CPP/7zip/Compress/Lzma2Decoder.h b/CPP/7zip/Compress/Lzma2Decoder.h index fd7ca2f3..a87912fb 100644 --- a/CPP/7zip/Compress/Lzma2Decoder.h +++ b/CPP/7zip/Compress/Lzma2Decoder.h @@ -15,7 +15,9 @@ namespace NLzma2 { class CDecoder: public ICompressCoder, public ICompressSetDecoderProperties2, + public ICompressSetFinishMode, public ICompressGetInStreamProcessedSize, + public ICompressSetBufSize, #ifndef NO_READ_FROM_CODER public ICompressSetInStream, public ICompressSetOutStreamSize, @@ -27,36 +29,49 @@ class CDecoder: Byte *_inBuf; UInt32 _inPos; UInt32 _inSize; - CLzma2Dec _state; + + bool _finishMode; bool _outSizeDefined; UInt64 _outSize; + UInt64 _inSizeProcessed; UInt64 _outSizeProcessed; + + UInt32 _inBufSize; + UInt32 _inBufSizeNew; + UInt32 _outStepSize; + + CLzma2Dec _state; public: + MY_QUERYINTERFACE_BEGIN2(ICompressCoder) + MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2) + MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode) + MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize) + MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize) #ifndef NO_READ_FROM_CODER - MY_UNKNOWN_IMP5( - ICompressSetDecoderProperties2, - ICompressGetInStreamProcessedSize, - ICompressSetInStream, - ICompressSetOutStreamSize, - ISequentialInStream) - #else - MY_UNKNOWN_IMP2( - ICompressSetDecoderProperties2, - ICompressGetInStreamProcessedSize) + MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) + MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize) + MY_QUERYINTERFACE_ENTRY(ISequentialInStream) #endif + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE - STDMETHOD(Code)(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); + STDMETHOD(SetFinishMode)(UInt32 finishMode); + STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); + STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); + STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); + STDMETHOD(SetInStream)(ISequentialInStream *inStream); STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); #ifndef NO_READ_FROM_CODER diff --git a/CPP/7zip/Compress/Lzma2Encoder.cpp b/CPP/7zip/Compress/Lzma2Encoder.cpp index 5e4c71be..dea297c4 100644 --- a/CPP/7zip/Compress/Lzma2Encoder.cpp +++ b/CPP/7zip/Compress/Lzma2Encoder.cpp @@ -19,14 +19,6 @@ HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep); namespace NLzma2 { -static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); } -static void SzBigFree(void *, void *address) { BigFree(address); } -static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; - -static void *SzAlloc(void *, size_t size) { return MyAlloc(size); } -static void SzFree(void *, void *address) { MyFree(address); } -static ISzAlloc g_Alloc = { SzAlloc, SzFree }; - CEncoder::CEncoder() { _encoder = 0; diff --git a/CPP/7zip/Compress/Lzma2Register.cpp b/CPP/7zip/Compress/Lzma2Register.cpp index cace871e..d684d9d0 100644 --- a/CPP/7zip/Compress/Lzma2Register.cpp +++ b/CPP/7zip/Compress/Lzma2Register.cpp @@ -6,15 +6,12 @@ #include "Lzma2Decoder.h" -static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::NLzma2::CDecoder); } #ifndef EXTRACT_ONLY #include "Lzma2Encoder.h" -static void *CreateCodecOut() { return (void *)(ICompressCoder *)(new NCompress::NLzma2::CEncoder); } -#else -#define CreateCodecOut 0 #endif -static CCodecInfo g_CodecInfo = - { CreateCodec, CreateCodecOut, 0x21, L"LZMA2", 1, false }; - -REGISTER_CODEC(LZMA2) +REGISTER_CODEC_E(LZMA2, + NCompress::NLzma2::CDecoder(), + NCompress::NLzma2::CEncoder(), + 0x21, + "LZMA2") diff --git a/CPP/7zip/Compress/LzmaDecoder.cpp b/CPP/7zip/Compress/LzmaDecoder.cpp index a7ee31ba..d96be8ce 100644 --- a/CPP/7zip/Compress/LzmaDecoder.cpp +++ b/CPP/7zip/Compress/LzmaDecoder.cpp @@ -25,20 +25,16 @@ namespace NCompress { namespace NLzma { CDecoder::CDecoder(): _inBuf(0), _propsWereSet(false), _outSizeDefined(false), - _inBufSize(1 << 20), - _outBufSize(1 << 22), - FinishStream(false), - NeedMoreInput(false) + _inBufSize(1 << 20), + _outBufSize(1 << 22), + FinishStream(false), + NeedMoreInput(false) { _inSizeProcessed = 0; _inPos = _inSize = 0; LzmaDec_Construct(&_state); } -static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } -static void SzFree(void *p, void *address) { p = p; MyFree(address); } -static ISzAlloc g_Alloc = { SzAlloc, SzFree }; - CDecoder::~CDecoder() { LzmaDec_Free(&_state, &g_Alloc); @@ -87,6 +83,12 @@ STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) return S_OK; } +STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode) +{ + FinishStream = (finishMode != 0); + return S_OK; +} + HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress) { if (_inBuf == 0 || !_propsWereSet) diff --git a/CPP/7zip/Compress/LzmaDecoder.h b/CPP/7zip/Compress/LzmaDecoder.h index 754eaa3f..f1f839a4 100644 --- a/CPP/7zip/Compress/LzmaDecoder.h +++ b/CPP/7zip/Compress/LzmaDecoder.h @@ -14,6 +14,7 @@ namespace NLzma { class CDecoder: public ICompressCoder, public ICompressSetDecoderProperties2, + public ICompressSetFinishMode, public ICompressSetBufSize, #ifndef NO_READ_FROM_CODER public ICompressSetInStream, @@ -45,6 +46,7 @@ class CDecoder: public: MY_QUERYINTERFACE_BEGIN2(ICompressCoder) MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2) + MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode) MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize) #ifndef NO_READ_FROM_CODER MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) @@ -57,6 +59,7 @@ public: STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + STDMETHOD(SetFinishMode)(UInt32 finishMode); STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); diff --git a/CPP/7zip/Compress/LzmaEncoder.cpp b/CPP/7zip/Compress/LzmaEncoder.cpp index 484d0452..0a7e294d 100644 --- a/CPP/7zip/Compress/LzmaEncoder.cpp +++ b/CPP/7zip/Compress/LzmaEncoder.cpp @@ -12,29 +12,21 @@ namespace NCompress { namespace NLzma { -static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); } -static void SzBigFree(void *, void *address) { BigFree(address); } -static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; - -static void *SzAlloc(void *, size_t size) { return MyAlloc(size); } -static void SzFree(void *, void *address) { MyFree(address); } -static ISzAlloc g_Alloc = { SzAlloc, SzFree }; - CEncoder::CEncoder() { - _encoder = 0; + _encoder = NULL; _encoder = LzmaEnc_Create(&g_Alloc); - if (_encoder == 0) + if (!_encoder) throw 1; } CEncoder::~CEncoder() { - if (_encoder != 0) + if (_encoder) LzmaEnc_Destroy(_encoder, &g_Alloc, &g_BigAlloc); } -inline wchar_t GetUpperChar(wchar_t c) +static inline wchar_t GetUpperChar(wchar_t c) { if (c >= 'a' && c <= 'z') c -= 0x20; @@ -51,22 +43,21 @@ static int ParseMatchFinder(const wchar_t *s, int *btMode, int *numHashBytes) int numHashBytesLoc = (int)(*s++ - L'0'); if (numHashBytesLoc < 4 || numHashBytesLoc > 4) return 0; - if (*s++ != 0) + if (*s != 0) return 0; *btMode = 0; *numHashBytes = numHashBytesLoc; return 1; } + if (c != L'B') return 0; - if (GetUpperChar(*s++) != L'T') return 0; int numHashBytesLoc = (int)(*s++ - L'0'); if (numHashBytesLoc < 2 || numHashBytesLoc > 4) return 0; - c = GetUpperChar(*s++); - if (c != L'\0') + if (*s != 0) return 0; *btMode = 1; *numHashBytes = numHashBytesLoc; diff --git a/CPP/7zip/Compress/LzmaRegister.cpp b/CPP/7zip/Compress/LzmaRegister.cpp index 96ed0bae..c12416f2 100644 --- a/CPP/7zip/Compress/LzmaRegister.cpp +++ b/CPP/7zip/Compress/LzmaRegister.cpp @@ -6,15 +6,12 @@ #include "LzmaDecoder.h" -static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::NLzma::CDecoder); } #ifndef EXTRACT_ONLY #include "LzmaEncoder.h" -static void *CreateCodecOut() { return (void *)(ICompressCoder *)(new NCompress::NLzma::CEncoder); } -#else -#define CreateCodecOut 0 #endif -static CCodecInfo g_CodecInfo = - { CreateCodec, CreateCodecOut, 0x030101, L"LZMA", 1, false }; - -REGISTER_CODEC(LZMA) +REGISTER_CODEC_E(LZMA, + NCompress::NLzma::CDecoder(), + NCompress::NLzma::CEncoder(), + 0x30101, + "LZMA") diff --git a/CPP/7zip/Compress/PpmdDecoder.cpp b/CPP/7zip/Compress/PpmdDecoder.cpp index c02f44f1..ce00343b 100644 --- a/CPP/7zip/Compress/PpmdDecoder.cpp +++ b/CPP/7zip/Compress/PpmdDecoder.cpp @@ -23,10 +23,6 @@ enum kStatus_Error }; -static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); } -static void SzBigFree(void *, void *address) { BigFree(address); } -static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; - CDecoder::~CDecoder() { ::MidFree(_outBuf); diff --git a/CPP/7zip/Compress/PpmdEncoder.cpp b/CPP/7zip/Compress/PpmdEncoder.cpp index 5bf83529..00ea9668 100644 --- a/CPP/7zip/Compress/PpmdEncoder.cpp +++ b/CPP/7zip/Compress/PpmdEncoder.cpp @@ -14,10 +14,6 @@ namespace NPpmd { static const UInt32 kBufSize = (1 << 20); -static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); } -static void SzBigFree(void *, void *address) { BigFree(address); } -static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; - static const Byte kOrders[10] = { 3, 4, 4, 5, 5, 6, 8, 16, 24, 32 }; void CEncProps::Normalize(int level) @@ -40,7 +36,7 @@ void CEncProps::Normalize(int level) } } } - if (Order == -1) Order = kOrders[level]; + if (Order == -1) Order = kOrders[(unsigned)level]; } CEncoder::CEncoder(): diff --git a/CPP/7zip/Compress/PpmdRegister.cpp b/CPP/7zip/Compress/PpmdRegister.cpp index 9f59fcdd..17f84bd0 100644 --- a/CPP/7zip/Compress/PpmdRegister.cpp +++ b/CPP/7zip/Compress/PpmdRegister.cpp @@ -1,5 +1,4 @@ // PpmdRegister.cpp -// 2009-05-30 : Igor Pavlov : Public domain #include "StdAfx.h" @@ -7,15 +6,12 @@ #include "PpmdDecoder.h" -static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::NPpmd::CDecoder); } #ifndef EXTRACT_ONLY #include "PpmdEncoder.h" -static void *CreateCodecOut() { return (void *)(ICompressCoder *)(new NCompress::NPpmd::CEncoder); } -#else -#define CreateCodecOut 0 #endif -static CCodecInfo g_CodecInfo = - { CreateCodec, CreateCodecOut, 0x030401, L"PPMD", 1, false }; - -REGISTER_CODEC(PPMD) +REGISTER_CODEC_E(PPMD, + NCompress::NPpmd::CDecoder(), + NCompress::NPpmd::CEncoder(), + 0x30401, + "PPMD") diff --git a/CPP/7zip/Compress/PpmdZip.cpp b/CPP/7zip/Compress/PpmdZip.cpp index 036f3c72..24dd32f2 100644 --- a/CPP/7zip/Compress/PpmdZip.cpp +++ b/CPP/7zip/Compress/PpmdZip.cpp @@ -12,10 +12,6 @@ namespace NCompress { namespace NPpmdZip { -static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); } -static void SzBigFree(void *, void *address) { BigFree(address); } -static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; - CDecoder::CDecoder(bool fullFileMode): _fullFileMode(fullFileMode) { @@ -260,14 +256,4 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream } } -/* -static void *CreateCodec() { return (void *)(ICompressCoder *)(new CDecoder(false)); } -static void *CreateCodecOut() { return (void *)(ICompressCoder *)(new CEncoder); } - -static CCodecInfo g_CodecInfo = - { CreateCodec, CreateCodecOut, 0x040162, L"PPMdZIP", 1, false }; - -REGISTER_CODEC(PPMdZIP) -*/ - }} diff --git a/CPP/7zip/Compress/RangeCoder.h b/CPP/7zip/Compress/RangeCoder.h deleted file mode 100644 index 0b0d44ae..00000000 --- a/CPP/7zip/Compress/RangeCoder.h +++ /dev/null @@ -1,201 +0,0 @@ -// Compress/RangeCoder.h -// 2013-01-10 : Igor Pavlov : Public domain - -#ifndef __COMPRESS_RANGE_CODER_H -#define __COMPRESS_RANGE_CODER_H - -#include "../Common/InBuffer.h" -#include "../Common/OutBuffer.h" - -namespace NCompress { -namespace NRangeCoder { - -const unsigned kNumTopBits = 24; -const UInt32 kTopValue = (1 << kNumTopBits); - -class CEncoder -{ - UInt32 _cacheSize; - Byte _cache; -public: - UInt64 Low; - UInt32 Range; - COutBuffer Stream; - bool Create(UInt32 bufSize) { return Stream.Create(bufSize); } - - void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); } - void Init() - { - Stream.Init(); - Low = 0; - Range = 0xFFFFFFFF; - _cacheSize = 1; - _cache = 0; - } - - void FlushData() - { - // Low += 1; - for (int i = 0; i < 5; i++) - ShiftLow(); - } - - HRESULT FlushStream() { return Stream.Flush(); } - - void Encode(UInt32 start, UInt32 size, UInt32 total) - { - Low += start * (Range /= total); - Range *= size; - while (Range < kTopValue) - { - Range <<= 8; - ShiftLow(); - } - } - - void ShiftLow() - { - if ((UInt32)Low < (UInt32)0xFF000000 || (unsigned)(Low >> 32) != 0) - { - Byte temp = _cache; - do - { - Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32))); - temp = 0xFF; - } - while (--_cacheSize != 0); - _cache = (Byte)((UInt32)Low >> 24); - } - _cacheSize++; - Low = (UInt32)Low << 8; - } - - void EncodeDirectBits(UInt32 value, int numBits) - { - for (numBits--; numBits >= 0; numBits--) - { - Range >>= 1; - Low += Range & (0 - ((value >> numBits) & 1)); - if (Range < kTopValue) - { - Range <<= 8; - ShiftLow(); - } - } - } - - void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol) - { - UInt32 newBound = (Range >> numTotalBits) * size0; - if (symbol == 0) - Range = newBound; - else - { - Low += newBound; - Range -= newBound; - } - while (Range < kTopValue) - { - Range <<= 8; - ShiftLow(); - } - } - - UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; } -}; - -class CDecoder -{ -public: - CInBuffer Stream; - UInt32 Range; - UInt32 Code; - bool Create(UInt32 bufSize) { return Stream.Create(bufSize); } - - void Normalize() - { - while (Range < kTopValue) - { - Code = (Code << 8) | Stream.ReadByte(); - Range <<= 8; - } - } - - void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); } - void Init() - { - Stream.Init(); - Code = 0; - Range = 0xFFFFFFFF; - for (int i = 0; i < 5; i++) - Code = (Code << 8) | Stream.ReadByte(); - } - - UInt32 GetThreshold(UInt32 total) - { - return (Code) / (Range /= total); - } - - void Decode(UInt32 start, UInt32 size) - { - Code -= start * Range; - Range *= size; - Normalize(); - } - - UInt32 DecodeDirectBits(int numTotalBits) - { - UInt32 range = Range; - UInt32 code = Code; - UInt32 result = 0; - for (int i = numTotalBits; i != 0; i--) - { - range >>= 1; - /* - result <<= 1; - if (code >= range) - { - code -= range; - result |= 1; - } - */ - UInt32 t = (code - range) >> 31; - code -= range & (t - 1); - result = (result << 1) | (1 - t); - - if (range < kTopValue) - { - code = (code << 8) | Stream.ReadByte(); - range <<= 8; - } - } - Range = range; - Code = code; - return result; - } - - UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) - { - UInt32 newBound = (Range >> numTotalBits) * size0; - UInt32 symbol; - if (Code < newBound) - { - symbol = 0; - Range = newBound; - } - else - { - symbol = 1; - Code -= newBound; - Range -= newBound; - } - Normalize(); - return symbol; - } - - UInt64 GetProcessedSize() { return Stream.GetProcessedSize(); } -}; - -}} - -#endif diff --git a/CPP/7zip/Compress/RangeCoderBit.h b/CPP/7zip/Compress/RangeCoderBit.h deleted file mode 100644 index 0eddd558..00000000 --- a/CPP/7zip/Compress/RangeCoderBit.h +++ /dev/null @@ -1,114 +0,0 @@ -// Compress/RangeCoderBit.h -// 2013-01-10 : Igor Pavlov : Public domain - -#ifndef __COMPRESS_RANGE_CODER_BIT_H -#define __COMPRESS_RANGE_CODER_BIT_H - -#include "RangeCoder.h" - -namespace NCompress { -namespace NRangeCoder { - -const unsigned kNumBitModelTotalBits = 11; -const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits); - -const unsigned kNumMoveReducingBits = 4; - -const unsigned kNumBitPriceShiftBits = 4; -const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits; - -extern UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; - -template <unsigned numMoveBits> -class CBitModel -{ -public: - UInt32 Prob; - void UpdateModel(UInt32 symbol) - { - /* - Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits; - Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits); - */ - if (symbol == 0) - Prob += (kBitModelTotal - Prob) >> numMoveBits; - else - Prob -= (Prob) >> numMoveBits; - } -public: - void Init() { Prob = kBitModelTotal / 2; } -}; - -template <unsigned numMoveBits> -class CBitEncoder: public CBitModel<numMoveBits> -{ -public: - void Encode(CEncoder *encoder, UInt32 symbol) - { - /* - encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol); - this->UpdateModel(symbol); - */ - UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob; - if (symbol == 0) - { - encoder->Range = newBound; - this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits; - } - else - { - encoder->Low += newBound; - encoder->Range -= newBound; - this->Prob -= (this->Prob) >> numMoveBits; - } - if (encoder->Range < kTopValue) - { - encoder->Range <<= 8; - encoder->ShiftLow(); - } - } - UInt32 GetPrice(UInt32 symbol) const - { - 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 <unsigned numMoveBits> -class CBitDecoder: public CBitModel<numMoveBits> -{ -public: - UInt32 Decode(CDecoder *decoder) - { - UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob; - if (decoder->Code < newBound) - { - decoder->Range = newBound; - this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits; - if (decoder->Range < kTopValue) - { - decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte(); - decoder->Range <<= 8; - } - return 0; - } - else - { - decoder->Range -= newBound; - decoder->Code -= newBound; - this->Prob -= (this->Prob) >> numMoveBits; - if (decoder->Range < kTopValue) - { - decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte(); - decoder->Range <<= 8; - } - return 1; - } - } -}; - -}} - -#endif diff --git a/CPP/7zip/Compress/Rar1Decoder.cpp b/CPP/7zip/Compress/Rar1Decoder.cpp index 8eb904df..12de7e19 100644 --- a/CPP/7zip/Compress/Rar1Decoder.cpp +++ b/CPP/7zip/Compress/Rar1Decoder.cpp @@ -9,13 +9,13 @@ namespace NCompress { namespace NRar1 { -static UInt32 PosL1[]={0,0,0,2,3,5,7,11,16,20,24,32,32, 256}; -static UInt32 PosL2[]={0,0,0,0,5,7,9,13,18,22,26,34,36, 256}; -static UInt32 PosHf0[]={0,0,0,0,0,8,16,24,33,33,33,33,33, 257}; -static UInt32 PosHf1[]={0,0,0,0,0,0,4,44,60,76,80,80,127, 257}; -static UInt32 PosHf2[]={0,0,0,0,0,0,2,7,53,117,233, 257,0}; -static UInt32 PosHf3[]={0,0,0,0,0,0,0,2,16,218,251, 257,0}; -static UInt32 PosHf4[]={0,0,0,0,0,0,0,0,0,255, 257,0,0}; +static const UInt32 PosL1[] = {0,0,0,2,3,5,7,11,16,20,24,32,32, 256}; +static const UInt32 PosL2[] = {0,0,0,0,5,7,9,13,18,22,26,34,36, 256}; +static const UInt32 PosHf0[] = {0,0,0,0,0,8,16,24,33,33,33,33,33, 257}; +static const UInt32 PosHf1[] = {0,0,0,0,0,0,4,44,60,76,80,80,127, 257}; +static const UInt32 PosHf2[] = {0,0,0,0,0,0,2,7,53,117,233, 257,0}; +static const UInt32 PosHf3[] = {0,0,0,0,0,0,0,2,16,218,251, 257,0}; +static const UInt32 PosHf4[] = {0,0,0,0,0,0,0,0,0,255, 257,0,0}; static const UInt32 kHistorySize = (1 << 16); @@ -67,18 +67,18 @@ 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 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 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}; +static const Byte kShortLen1 [] = {1,3,4,4,5,6,7,8,8,4,4,5,6,6 }; +static const Byte kShortLen1a[] = {1,4,4,4,5,6,7,8,8,4,4,5,6,6,4 }; +static const Byte kShortLen2 [] = {2,3,3,3,4,4,5,6,6,4,4,5,6,6 }; +static const Byte kShortLen2a[] = {2,3,3,4,4,4,5,6,6,4,4,5,6,6,4 }; +static const UInt32 kShortXor1[] = {0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0}; +static const UInt32 kShortXor2[] = {0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0}; HRESULT CDecoder::ShortLZ() { UInt32 len, saveLen, dist; int distancePlace; - Byte *kShortLen; + const Byte *kShortLen; const UInt32 *kShortXor; NumHuf = 0; @@ -143,17 +143,18 @@ HRESULT CDecoder::ShortLZ() AvrLn1 -= AvrLn1 >> 4; distancePlace = DecodeNum(PosHf2) & 0xff; - dist = ChSetA[distancePlace]; + dist = ChSetA[(unsigned)distancePlace]; if (--distancePlace != -1) { PlaceA[dist]--; - UInt32 lastDistance = ChSetA[distancePlace]; + UInt32 lastDistance = ChSetA[(unsigned)distancePlace]; PlaceA[lastDistance]++; - ChSetA[distancePlace + 1] = lastDistance; - ChSetA[distancePlace] = dist; + ChSetA[(unsigned)distancePlace + 1] = lastDistance; + ChSetA[(unsigned)distancePlace] = dist; } len += 2; } + m_RepDists[m_RepDistPtr++] = dist; m_RepDistPtr &= 3; LastLength = len; @@ -210,6 +211,7 @@ HRESULT CDecoder::LongLZ() AvrPlcB += distancePlace; AvrPlcB -= AvrPlcB >> 8; + for (;;) { dist = ChSetB[distancePlace & 0xff]; @@ -226,6 +228,7 @@ HRESULT CDecoder::LongLZ() dist = ((dist & 0xff00) >> 1) | ReadBits(7); oldAvr3 = AvrLn3; + if (len != 1 && len != 4) if (len == 0 && dist <= MaxDist3) { @@ -235,19 +238,24 @@ HRESULT CDecoder::LongLZ() else if (AvrLn3 > 0) AvrLn3--; + len += 3; + if (dist >= MaxDist3) len++; if (dist <= 256) len += 8; + if (oldAvr3 > 0xb0 || AvrPlc >= 0x2a00 && oldAvr2 < 0x40) MaxDist3 = 0x7f00; else MaxDist3 = 0x2001; + m_RepDists[m_RepDistPtr++] = --dist; m_RepDistPtr &= 3; LastLength = len; LastDist = dist; + return CopyBlock(dist, len); } @@ -264,6 +272,7 @@ HRESULT CDecoder::HuffDecode() else if (AvrPlc > 0x35ff) bytePlace = DecodeNum(PosHf2); else if (AvrPlc > 0x0dff) bytePlace = DecodeNum(PosHf1); else bytePlace = DecodeNum(PosHf0); + if (StMode) { if (--bytePlace == -1) @@ -284,10 +293,12 @@ HRESULT CDecoder::HuffDecode() } else if (NumHuf++ >= 16 && FlagsCnt == 0) StMode = 1; + bytePlace &= 0xff; AvrPlc += bytePlace; AvrPlc -= AvrPlc >> 8; Nhfb+=16; + if (Nhfb > 0xff) { Nhfb=0x90; diff --git a/CPP/7zip/Compress/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar2Decoder.cpp index c4312f9b..6f42d2e6 100644 --- a/CPP/7zip/Compress/Rar2Decoder.cpp +++ b/CPP/7zip/Compress/Rar2Decoder.cpp @@ -20,19 +20,22 @@ Byte CFilter::Decode(int &channelDelta, Byte deltaByte) int predictedValue = ((8 * LastChar + K1 * D1 + K2 * D2 + K3 * D3 + K4 * D4 + K5 * channelDelta) >> 3); Byte realValue = (Byte)(predictedValue - deltaByte); - int i = ((int)(signed char)deltaByte) << 3; + + { + int i = ((int)(signed char)deltaByte) << 3; - Dif[0] += abs(i); - Dif[1] += abs(i - D1); - Dif[2] += abs(i + D1); - Dif[3] += abs(i - D2); - Dif[4] += abs(i + D2); - Dif[5] += abs(i - D3); - Dif[6] += abs(i + D3); - Dif[7] += abs(i - D4); - Dif[8] += abs(i + D4); - Dif[9] += abs(i - channelDelta); - Dif[10] += abs(i + channelDelta); + Dif[0] += abs(i); + Dif[1] += abs(i - D1); + Dif[2] += abs(i + D1); + Dif[3] += abs(i - D2); + Dif[4] += abs(i + D2); + Dif[5] += abs(i - D3); + Dif[6] += abs(i + D3); + Dif[7] += abs(i - D4); + Dif[8] += abs(i + D4); + Dif[9] += abs(i - channelDelta); + Dif[10] += abs(i + channelDelta); + } channelDelta = LastDelta = (signed char)(realValue - LastChar); LastChar = realValue; @@ -42,7 +45,8 @@ Byte CFilter::Decode(int &channelDelta, Byte deltaByte) UInt32 minDif = Dif[0]; UInt32 numMinDif = 0; Dif[0] = 0; - for (i = 1; i < sizeof(Dif) / sizeof(Dif[0]); i++) + + for (unsigned i = 1; i < ARRAY_SIZE(Dif); i++) { if (Dif[i] < minDif) { @@ -51,6 +55,7 @@ Byte CFilter::Decode(int &channelDelta, Byte deltaByte) } Dif[i] = 0; } + switch(numMinDif) { case 1: if (K1 >= -16) K1--; break; @@ -65,14 +70,13 @@ Byte CFilter::Decode(int &channelDelta, Byte deltaByte) case 10:if (K5 < 16) K5++; break; } } + return realValue; } } static const UInt32 kHistorySize = 1 << 20; -static const int kNumStats = 11; - static const UInt32 kWindowReservSize = (1 << 22) + 256; CDecoder::CDecoder(): @@ -83,14 +87,14 @@ CDecoder::CDecoder(): void CDecoder::InitStructures() { m_MmFilter.Init(); - for (int i = 0; i < kNumRepDists; i++) + for (unsigned i = 0; i < kNumRepDists; i++) m_RepDists[i] = 0; m_RepDistPtr = 0; m_LastLength = 0; memset(m_LastLevels, 0, kMaxTableSize); } -UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); } +UInt32 CDecoder::ReadBits(unsigned numBits) { return m_InBitStream.ReadBits(numBits); } #define RIF(x) { if (!(x)) return false; } @@ -102,7 +106,9 @@ bool CDecoder::ReadTables(void) if (ReadBits(1) == 0) memset(m_LastLevels, 0, kMaxTableSize); - int numLevels; + + unsigned numLevels; + if (m_AudioMode) { m_NumChannels = ReadBits(2) + 1; @@ -113,11 +119,13 @@ bool CDecoder::ReadTables(void) else numLevels = kHeapTablesSizesSum; - int i; + unsigned i; for (i = 0; i < kLevelTableSize; i++) levelLevels[i] = (Byte)ReadBits(4); RIF(m_LevelDecoder.SetCodeLengths(levelLevels)); + i = 0; + while (i < numLevels) { UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); @@ -130,24 +138,25 @@ bool CDecoder::ReadTables(void) { if (number == kTableLevelRepNumber) { - int t = ReadBits(2) + 3; - for (int reps = t; reps > 0 && i < numLevels ; reps--, i++) + unsigned t = ReadBits(2) + 3; + for (unsigned reps = t; reps > 0 && i < numLevels; reps--, i++) newLevels[i] = newLevels[i - 1]; } else { - int num; + unsigned num; if (number == kTableLevel0Number) num = ReadBits(3) + 3; else if (number == kTableLevel0Number2) num = ReadBits(7) + 11; else return false; - for (;num > 0 && i < numLevels; num--) + for (; num > 0 && i < numLevels; num--) newLevels[i++] = 0; } } } + if (m_AudioMode) for (i = 0; i < m_NumChannels; i++) { @@ -159,6 +168,7 @@ bool CDecoder::ReadTables(void) RIF(m_DistDecoder.SetCodeLengths(&newLevels[kMainTableSize])); RIF(m_LenDecoder.SetCodeLengths(&newLevels[kMainTableSize + kDistTableSize])); } + memcpy(m_LastLevels, newLevels, kMaxTableSize); return true; } diff --git a/CPP/7zip/Compress/Rar2Decoder.h b/CPP/7zip/Compress/Rar2Decoder.h index 44b262c1..3a0535cc 100644 --- a/CPP/7zip/Compress/Rar2Decoder.h +++ b/CPP/7zip/Compress/Rar2Decoder.h @@ -18,10 +18,10 @@ namespace NCompress { namespace NRar2 { -const UInt32 kNumRepDists = 4; -const UInt32 kDistTableSize = 48; +const unsigned kNumRepDists = 4; +const unsigned kDistTableSize = 48; -const int kMMTableSize = 256 + 1; +const unsigned kMMTableSize = 256 + 1; const UInt32 kMainTableSize = 298; const UInt32 kLenTableSize = 28; @@ -89,14 +89,14 @@ struct CFilter }; -const int kNumChanelsMax = 4; +const unsigned kNumChanelsMax = 4; class CFilter2 { public: CFilter m_Filters[kNumChanelsMax]; int m_ChannelDelta; - int CurrentChannel; + unsigned CurrentChannel; void Init() { memset(this, 0, sizeof(*this)); } Byte Decode(Byte delta) @@ -110,7 +110,7 @@ public: typedef NBitm::CDecoder<CInBuffer> CBitDecoder; -const int kNumHuffmanBits = 15; +const unsigned kNumHuffmanBits = 15; class CDecoder : public ICompressCoder, @@ -128,7 +128,7 @@ class CDecoder : bool m_AudioMode; NMultimedia::CFilter2 m_MmFilter; - int m_NumChannels; + unsigned m_NumChannels; UInt32 m_RepDists[kNumRepDists]; UInt32 m_RepDistPtr; @@ -141,7 +141,7 @@ class CDecoder : bool m_IsSolid; void InitStructures(); - UInt32 ReadBits(int numBits); + UInt32 ReadBits(unsigned numBits); bool ReadTables(); bool ReadLastTables(); diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp index 3c70e1c0..f0553c85 100644 --- a/CPP/7zip/Compress/Rar3Decoder.cpp +++ b/CPP/7zip/Compress/Rar3Decoder.cpp @@ -15,10 +15,6 @@ namespace NCompress { namespace NRar3 { -static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); } -static void SzBigFree(void *, void *address) { BigFree(address); } -static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; - static const UInt32 kNumAlignReps = 15; static const UInt32 kSymbolReadTable = 256; diff --git a/CPP/7zip/Compress/Rar3Vm.cpp b/CPP/7zip/Compress/Rar3Vm.cpp index 5b113bfa..3cbfb0e1 100644 --- a/CPP/7zip/Compress/Rar3Vm.cpp +++ b/CPP/7zip/Compress/Rar3Vm.cpp @@ -696,11 +696,11 @@ void CProgram::ReadProgram(const Byte *code, UInt32 codeSize) cmd->OpCode = (ECommand)inp.ReadBits(3); else cmd->OpCode = (ECommand)(8 + inp.ReadBits(5)); - if (kCmdFlags[cmd->OpCode] & CF_BYTEMODE) + if (kCmdFlags[(unsigned)cmd->OpCode] & CF_BYTEMODE) cmd->ByteMode = (inp.ReadBit()) ? true : false; else cmd->ByteMode = 0; - int opNum = (kCmdFlags[cmd->OpCode] & CF_OPMASK); + int opNum = (kCmdFlags[(unsigned)cmd->OpCode] & CF_OPMASK); if (opNum > 0) { DecodeArg(inp, cmd->Op1, cmd->ByteMode); @@ -708,7 +708,7 @@ void CProgram::ReadProgram(const Byte *code, UInt32 codeSize) DecodeArg(inp, cmd->Op2, cmd->ByteMode); else { - if (cmd->Op1.Type == OP_TYPE_INT && (kCmdFlags[cmd->OpCode] & (CF_JUMP | CF_PROC))) + if (cmd->Op1.Type == OP_TYPE_INT && (kCmdFlags[(unsigned)cmd->OpCode] & (CF_JUMP | CF_PROC))) { int dist = cmd->Op1.Data; if (dist >= 256) @@ -784,7 +784,7 @@ kStdFilters[]= static int FindStandardFilter(const Byte *code, UInt32 codeSize) { UInt32 crc = CrcCalc(code, codeSize); - for (int i = 0; i < sizeof(kStdFilters) / sizeof(kStdFilters[0]); i++) + for (unsigned i = 0; i < ARRAY_SIZE(kStdFilters); i++) { const CStandardFilterSignature &sfs = kStdFilters[i]; if (sfs.CRC == crc && sfs.Length == codeSize) @@ -857,6 +857,7 @@ static inline UInt32 ItaniumGetOpType(const Byte *data, int bitPos) return (data[(unsigned int)bitPos >> 3] >> (bitPos & 7)) & 0xF; } +static const Byte kCmdMasks[16] = {4,4,6,6,0,0,7,7,4,4,0,0,4,4,0,0}; static void ItaniumDecode(Byte *data, UInt32 dataSize, UInt32 fileOffset) { @@ -867,7 +868,6 @@ static void ItaniumDecode(Byte *data, UInt32 dataSize, UInt32 fileOffset) int b = (data[0] & 0x1F) - 0x10; if (b >= 0) { - static Byte kCmdMasks[16] = {4,4,6,6,0,0,7,7,4,4,0,0,4,4,0,0}; Byte cmdMask = kCmdMasks[b]; if (cmdMask != 0) for (int i = 0; i < 3; i++) @@ -993,7 +993,7 @@ static void AudioDecode(Byte *srcData, UInt32 dataSize, UInt32 numChannels) { UInt32 minDif = dif[0], numMinDif = 0; dif[0] = 0; - for (int j = 1; j < sizeof(dif) / sizeof(dif[0]); j++) + for (unsigned j = 1; j < ARRAY_SIZE(dif); j++) { if (dif[j] < minDif) { @@ -1029,7 +1029,7 @@ static UInt32 UpCaseDecode(Byte *data, UInt32 dataSize) return destPos - dataSize; } -void CVm::ExecuteStandardFilter(int filterIndex) +void CVm::ExecuteStandardFilter(unsigned filterIndex) { UInt32 dataSize = R[4]; if (dataSize >= kGlobalOffset) diff --git a/CPP/7zip/Compress/Rar3Vm.h b/CPP/7zip/Compress/Rar3Vm.h index 55842b90..23f4abab 100644 --- a/CPP/7zip/Compress/Rar3Vm.h +++ b/CPP/7zip/Compress/Rar3Vm.h @@ -157,7 +157,7 @@ private: bool ExecuteCode(const CProgram *prg); #ifdef RARVM_STANDARD_FILTERS - void ExecuteStandardFilter(int filterIndex); + void ExecuteStandardFilter(unsigned filterIndex); #endif Byte *Mem; diff --git a/CPP/7zip/Compress/RarCodecsRegister.cpp b/CPP/7zip/Compress/RarCodecsRegister.cpp index e3f6a05c..66fcc9a9 100644 --- a/CPP/7zip/Compress/RarCodecsRegister.cpp +++ b/CPP/7zip/Compress/RarCodecsRegister.cpp @@ -8,19 +8,19 @@ #include "Rar2Decoder.h" #include "Rar3Decoder.h" -#define CREATE_CODEC(x) static void *CreateCodec ## x() { return (void *)(ICompressCoder *)(new NCompress::NRar ## x::CDecoder); } +#define CREATE_CODEC(x) REGISTER_CODEC_CREATE(CreateCodec ## x, NCompress::NRar ## x::CDecoder()) CREATE_CODEC(1) CREATE_CODEC(2) CREATE_CODEC(3) -#define RAR_CODEC(x, name) { CreateCodec ## x, 0, 0x040300 + x, L"Rar" name, 1, false } +#define RAR_CODEC(x, name) { CreateCodec ## x, NULL, 0x40300 + x, "Rar" name, 1, false } -static CCodecInfo g_CodecsInfo[] = +REGISTER_CODECS_VAR { - RAR_CODEC(1, L"1"), - RAR_CODEC(2, L"2"), - RAR_CODEC(3, L"3"), + RAR_CODEC(1, "1"), + RAR_CODEC(2, "2"), + RAR_CODEC(3, "3"), }; REGISTER_CODECS(Rar) |