summaryrefslogtreecommitdiffstats
path: root/other-licenses/7zstub/src/CPP/7zip/Compress
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@wolfbeast.com>2019-04-05 20:01:10 +0200
committerwolfbeast <mcwerewolf@wolfbeast.com>2019-04-05 20:01:10 +0200
commitc3b63b831cd2c64700e875b28540212c7c881ac6 (patch)
treeedd98fcbd2004d3b562904f822bf6c3322fc7f52 /other-licenses/7zstub/src/CPP/7zip/Compress
parentd432e068a21c815d5d5e7bcbc1cc8c6e77a7d1e0 (diff)
parentcc07da9cb4d6e7a53f8d953427ffc2bca2e0c2df (diff)
downloadUXP-c3b63b831cd2c64700e875b28540212c7c881ac6.tar
UXP-c3b63b831cd2c64700e875b28540212c7c881ac6.tar.gz
UXP-c3b63b831cd2c64700e875b28540212c7c881ac6.tar.lz
UXP-c3b63b831cd2c64700e875b28540212c7c881ac6.tar.xz
UXP-c3b63b831cd2c64700e875b28540212c7c881ac6.zip
Merge branch 'master' into 816
Diffstat (limited to 'other-licenses/7zstub/src/CPP/7zip/Compress')
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/Bcj2Coder.cpp666
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/Bcj2Coder.h120
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/Bcj2Register.cpp24
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/BcjCoder.cpp24
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/BcjCoder.h31
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/BcjRegister.cpp17
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/BranchMisc.cpp23
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/BranchMisc.h35
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/BranchRegister.cpp41
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/ByteSwap.cpp92
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/CodecExports.cpp344
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/CopyCoder.cpp120
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/CopyCoder.h49
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/CopyRegister.cpp15
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/DeltaFilter.cpp128
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/Lzma2Decoder.cpp265
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/Lzma2Decoder.h96
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/Lzma2Encoder.cpp122
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/Lzma2Encoder.h42
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/Lzma2Register.cpp22
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/LzmaDecoder.cpp343
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/LzmaDecoder.h113
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/LzmaEncoder.cpp182
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/LzmaEncoder.h46
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/LzmaRegister.cpp22
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/PpmdDecoder.cpp170
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/PpmdDecoder.h86
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/PpmdEncoder.cpp152
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/PpmdEncoder.h58
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/PpmdRegister.cpp22
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/StdAfx.h8
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/XzDecoder.cpp150
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/XzDecoder.h92
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/XzEncoder.cpp245
-rw-r--r--other-licenses/7zstub/src/CPP/7zip/Compress/XzEncoder.h46
35 files changed, 4011 insertions, 0 deletions
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/Bcj2Coder.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/Bcj2Coder.cpp
new file mode 100644
index 000000000..4e083bf19
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/Bcj2Coder.cpp
@@ -0,0 +1,666 @@
+// Bcj2Coder.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/Alloc.h"
+
+#include "../Common/StreamUtils.h"
+
+#include "Bcj2Coder.h"
+
+namespace NCompress {
+namespace NBcj2 {
+
+CBaseCoder::CBaseCoder()
+{
+ for (int i = 0; i < BCJ2_NUM_STREAMS + 1; i++)
+ {
+ _bufs[i] = NULL;
+ _bufsCurSizes[i] = 0;
+ _bufsNewSizes[i] = (1 << 18);
+ }
+}
+
+CBaseCoder::~CBaseCoder()
+{
+ for (int i = 0; i < BCJ2_NUM_STREAMS + 1; i++)
+ ::MidFree(_bufs[i]);
+}
+
+HRESULT CBaseCoder::Alloc(bool allocForOrig)
+{
+ 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;
+}
+
+
+
+#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)
+{
+ 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 * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams,
+ ISequentialOutStream * const *outStreams, const UInt64 * const * /* outSizes */, UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ if (numInStreams != 1 || numOutStreams != BCJ2_NUM_STREAMS)
+ return E_INVALIDARG;
+
+ RINOK(Alloc());
+
+ UInt32 fileSize_for_Conv = 0;
+ if (inSizes && inSizes[0])
+ {
+ UInt64 inSize = *inSizes[0];
+ if (inSize <= BCJ2_FileSize_MAX)
+ fileSize_for_Conv = (UInt32)inSize;
+ }
+
+ 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++)
+ {
+ enc.bufs[i] = _bufs[i];
+ enc.lims[i] = _bufs[i] + _bufsCurSizes[i];
+ }
+ }
+
+ 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;
+
+ Bcj2Enc_Init(&enc);
+
+ enc.fileIp = 0;
+ enc.fileSize = fileSize_for_Conv;
+
+ enc.relatLimit = _relatLim;
+
+ enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE;
+
+ bool needSubSize = false;
+ UInt64 subStreamIndex = 0;
+ UInt64 subStreamStartPos = 0;
+ bool readWasFinished = false;
+
+ for (;;)
+ {
+ if (needSubSize && getSubStreamSize)
+ {
+ enc.fileIp = 0;
+ enc.fileSize = fileSize_for_Conv;
+ enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE;
+
+ for (;;)
+ {
+ UInt64 subStreamSize = 0;
+ HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize);
+ needSubSize = false;
+
+ if (result == S_OK)
+ {
+ UInt64 newEndPos = subStreamStartPos + subStreamSize;
+
+ bool isAccurateEnd = (newEndPos < totalStreamRead ||
+ (newEndPos <= totalStreamRead && readWasFinished));
+
+ if (newEndPos <= currentInPos && isAccurateEnd)
+ {
+ subStreamStartPos = newEndPos;
+ subStreamIndex++;
+ continue;
+ }
+
+ enc.srcLim = _bufs[BCJ2_NUM_STREAMS] + numBytes_in_ReadBuf;
+
+ if (isAccurateEnd)
+ {
+ // 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;
+ }
+
+ if (subStreamSize <= BCJ2_FileSize_MAX)
+ {
+ enc.fileIp = enc.ip + (UInt32)(subStreamStartPos - currentInPos);
+ enc.fileSize = (UInt32)subStreamSize;
+ }
+ break;
+ }
+
+ if (result == S_FALSE)
+ break;
+ if (result == E_NOTIMPL)
+ {
+ getSubStreamSize.Release();
+ break;
+ }
+ return result;
+ }
+ }
+
+ 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]))
+ {
+ enc.srcLim = _bufs[BCJ2_NUM_STREAMS] + numBytes_in_ReadBuf;
+ continue;
+ }
+
+ 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)
+ {
+ readWasFinished = true;
+ continue;
+ }
+
+ numBytes_in_ReadBuf = curSize;
+ totalStreamRead += numBytes_in_ReadBuf;
+ enc.srcLim = _bufs[BCJ2_NUM_STREAMS] + numBytes_in_ReadBuf;
+ }
+
+ if (progress && currentInPos - prevProgress >= (1 << 20))
+ {
+ 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(&currentInPos, &outSize2));
+ }
+ }
+
+ 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 * 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(...) { return E_FAIL; }
+}
+
+#endif
+
+
+
+
+
+
+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)
+{
+ _finishMode = (finishMode != 0);
+ return S_OK;
+}
+
+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 != BCJ2_NUM_STREAMS || numOutStreams != 1)
+ return E_INVALIDARG;
+
+ RINOK(Alloc());
+
+ InitCommon();
+
+ dec.destLim = dec.dest = _bufs[BCJ2_NUM_STREAMS];
+
+ UInt64 outSizeProcessed = 0;
+ UInt64 prevProgress = 0;
+
+ HRESULT res = S_OK;
+
+ for (;;)
+ {
+ if (Bcj2Dec_Decode(&dec) != SZ_OK)
+ return S_FALSE;
+
+ if (dec.state < BCJ2_NUM_STREAMS)
+ {
+ 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;
+ }
+ else // if (dec.state <= BCJ2_STATE_ORIG)
+ {
+ 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;
+ }
+ }
+
+ if (progress)
+ {
+ const UInt64 outSize2 = outSizeProcessed + (dec.dest - _bufs[BCJ2_NUM_STREAMS]);
+ if (outSize2 - prevProgress >= (1 << 22))
+ {
+ const 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;
+ }
+ }
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::SetInStream2(UInt32 streamIndex, ISequentialInStream *inStream)
+{
+ _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)
+ {
+ 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;
+ */
+ }
+
+ return res;
+}
+
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize2(UInt32 streamIndex, UInt64 *value)
+{
+ const size_t rem = dec.lims[streamIndex] - dec.bufs[streamIndex] + _extraReadSizes[streamIndex];
+ *value = _inStreamsProcessed[streamIndex] - rem;
+ return S_OK;
+}
+
+}}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/Bcj2Coder.h b/other-licenses/7zstub/src/CPP/7zip/Compress/Bcj2Coder.h
new file mode 100644
index 000000000..666bf8c4c
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/Bcj2Coder.h
@@ -0,0 +1,120 @@
+// Bcj2Coder.h
+
+#ifndef __COMPRESS_BCJ2_CODER_H
+#define __COMPRESS_BCJ2_CODER_H
+
+#include "../../../C/Bcj2.h"
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+
+namespace NCompress {
+namespace NBcj2 {
+
+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 ICompressSetCoderProperties,
+ public ICompressSetBufSize,
+ public CMyUnknownImp,
+ public CBaseCoder
+{
+ UInt32 _relatLim;
+
+ 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_IMP3(ICompressCoder2, ICompressSetCoderProperties, ICompressSetBufSize)
+
+ 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);
+
+ STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size);
+ STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size);
+
+ CEncoder();
+ ~CEncoder();
+};
+
+#endif
+
+class CDecoder:
+ public ICompressCoder2,
+ public ICompressSetFinishMode,
+ public ICompressGetInStreamProcessedSize2,
+ public ICompressSetInStream2,
+ public ISequentialInStream,
+ public ICompressSetOutStreamSize,
+ public ICompressSetBufSize,
+ public CMyUnknownImp,
+ public CBaseCoder
+{
+ 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_IMP7(
+ ICompressCoder2,
+ ICompressSetFinishMode,
+ ICompressGetInStreamProcessedSize2,
+ ICompressSetInStream2,
+ ISequentialInStream,
+ ICompressSetOutStreamSize,
+ ICompressSetBufSize
+ );
+
+ 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(GetInStreamProcessedSize2)(UInt32 streamIndex, UInt64 *value);
+
+ 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);
+
+ CDecoder();
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/Bcj2Register.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/Bcj2Register.cpp
new file mode 100644
index 000000000..bce617892
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/Bcj2Register.cpp
@@ -0,0 +1,24 @@
+// Bcj2Register.cpp
+
+#include "StdAfx.h"
+
+#include "../Common/RegisterCodec.h"
+
+#include "Bcj2Coder.h"
+
+namespace NCompress {
+namespace NBcj2 {
+
+REGISTER_CODEC_CREATE_2(CreateCodec, CDecoder(), ICompressCoder2)
+#ifndef EXTRACT_ONLY
+REGISTER_CODEC_CREATE_2(CreateCodecOut, CEncoder(), ICompressCoder2)
+#else
+#define CreateCodecOut NULL
+#endif
+
+REGISTER_CODEC_VAR
+ { CreateCodec, CreateCodecOut, 0x303011B, "BCJ2", 4, false };
+
+REGISTER_CODEC(BCJ2)
+
+}}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/BcjCoder.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/BcjCoder.cpp
new file mode 100644
index 000000000..a50360c19
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/BcjCoder.cpp
@@ -0,0 +1,24 @@
+// BcjCoder.cpp
+
+#include "StdAfx.h"
+
+#include "BcjCoder.h"
+
+namespace NCompress {
+namespace NBcj {
+
+STDMETHODIMP CCoder::Init()
+{
+ _bufferPos = 0;
+ x86_Convert_Init(_prevMask);
+ return S_OK;
+}
+
+STDMETHODIMP_(UInt32) CCoder::Filter(Byte *data, UInt32 size)
+{
+ UInt32 processed = (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, _encode);
+ _bufferPos += processed;
+ return processed;
+}
+
+}}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/BcjCoder.h b/other-licenses/7zstub/src/CPP/7zip/Compress/BcjCoder.h
new file mode 100644
index 000000000..475dfe55a
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/BcjCoder.h
@@ -0,0 +1,31 @@
+// BcjCoder.h
+
+#ifndef __COMPRESS_BCJ_CODER_H
+#define __COMPRESS_BCJ_CODER_H
+
+#include "../../../C/Bra.h"
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+
+namespace NCompress {
+namespace NBcj {
+
+class CCoder:
+ public ICompressFilter,
+ public CMyUnknownImp
+{
+ UInt32 _bufferPos;
+ UInt32 _prevMask;
+ int _encode;
+public:
+ MY_UNKNOWN_IMP1(ICompressFilter);
+ INTERFACE_ICompressFilter(;)
+
+ CCoder(int encode): _bufferPos(0), _encode(encode) { x86_Convert_Init(_prevMask); }
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/BcjRegister.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/BcjRegister.cpp
new file mode 100644
index 000000000..48cc057fa
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/BcjRegister.cpp
@@ -0,0 +1,17 @@
+// BcjRegister.cpp
+
+#include "StdAfx.h"
+
+#include "../Common/RegisterCodec.h"
+
+#include "BcjCoder.h"
+
+namespace NCompress {
+namespace NBcj {
+
+REGISTER_FILTER_E(BCJ,
+ CCoder(false),
+ CCoder(true),
+ 0x3030103, "BCJ")
+
+}}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/BranchMisc.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/BranchMisc.cpp
new file mode 100644
index 000000000..d5a90f179
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/BranchMisc.cpp
@@ -0,0 +1,23 @@
+// BranchMisc.cpp
+
+#include "StdAfx.h"
+
+#include "BranchMisc.h"
+
+namespace NCompress {
+namespace NBranch {
+
+STDMETHODIMP CCoder::Init()
+{
+ _bufferPos = 0;
+ return S_OK;
+}
+
+STDMETHODIMP_(UInt32) CCoder::Filter(Byte *data, UInt32 size)
+{
+ UInt32 processed = (UInt32)BraFunc(data, size, _bufferPos, _encode);
+ _bufferPos += processed;
+ return processed;
+}
+
+}}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/BranchMisc.h b/other-licenses/7zstub/src/CPP/7zip/Compress/BranchMisc.h
new file mode 100644
index 000000000..02a56c390
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/BranchMisc.h
@@ -0,0 +1,35 @@
+// BranchMisc.h
+
+#ifndef __COMPRESS_BRANCH_MISC_H
+#define __COMPRESS_BRANCH_MISC_H
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+
+EXTERN_C_BEGIN
+
+typedef SizeT (*Func_Bra)(Byte *data, SizeT size, UInt32 ip, int encoding);
+
+EXTERN_C_END
+
+namespace NCompress {
+namespace NBranch {
+
+class CCoder:
+ public ICompressFilter,
+ public CMyUnknownImp
+{
+ UInt32 _bufferPos;
+ int _encode;
+ Func_Bra BraFunc;
+public:
+ MY_UNKNOWN_IMP1(ICompressFilter);
+ INTERFACE_ICompressFilter(;)
+
+ CCoder(Func_Bra bra, int encode): _bufferPos(0), _encode(encode), BraFunc(bra) {}
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/BranchRegister.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/BranchRegister.cpp
new file mode 100644
index 000000000..b83c6bcbd
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/BranchRegister.cpp
@@ -0,0 +1,41 @@
+// BranchRegister.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/Bra.h"
+
+#include "../Common/RegisterCodec.h"
+
+#include "BranchMisc.h"
+
+namespace NCompress {
+namespace NBranch {
+
+#define CREATE_BRA(n) \
+ REGISTER_FILTER_CREATE(CreateBra_Decoder_ ## n, CCoder(n ## _Convert, false)) \
+ REGISTER_FILTER_CREATE(CreateBra_Encoder_ ## n, CCoder(n ## _Convert, true)) \
+
+CREATE_BRA(PPC)
+CREATE_BRA(IA64)
+CREATE_BRA(ARM)
+CREATE_BRA(ARMT)
+CREATE_BRA(SPARC)
+
+#define METHOD_ITEM(n, id, name) \
+ REGISTER_FILTER_ITEM( \
+ CreateBra_Decoder_ ## n, \
+ CreateBra_Encoder_ ## n, \
+ 0x3030000 + id, name)
+
+REGISTER_CODECS_VAR
+{
+ 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/other-licenses/7zstub/src/CPP/7zip/Compress/ByteSwap.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/ByteSwap.cpp
new file mode 100644
index 000000000..ee103afe7
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/ByteSwap.cpp
@@ -0,0 +1,92 @@
+// ByteSwap.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+
+#include "../Common/RegisterCodec.h"
+
+namespace NCompress {
+namespace NByteSwap {
+
+class CByteSwap2:
+ public ICompressFilter,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(ICompressFilter);
+ INTERFACE_ICompressFilter(;)
+};
+
+class CByteSwap4:
+ public ICompressFilter,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(ICompressFilter);
+ INTERFACE_ICompressFilter(;)
+};
+
+STDMETHODIMP CByteSwap2::Init() { return S_OK; }
+
+STDMETHODIMP_(UInt32) CByteSwap2::Filter(Byte *data, UInt32 size)
+{
+ const UInt32 kStep = 2;
+ if (size < kStep)
+ return 0;
+ size &= ~(kStep - 1);
+
+ const Byte *end = data + (size_t)size;
+
+ do
+ {
+ Byte b0 = data[0];
+ data[0] = data[1];
+ data[1] = b0;
+ data += kStep;
+ }
+ while (data != end);
+
+ return size;
+}
+
+STDMETHODIMP CByteSwap4::Init() { return S_OK; }
+
+STDMETHODIMP_(UInt32) CByteSwap4::Filter(Byte *data, UInt32 size)
+{
+ const UInt32 kStep = 4;
+ if (size < kStep)
+ return 0;
+ size &= ~(kStep - 1);
+
+ const Byte *end = data + (size_t)size;
+
+ do
+ {
+ Byte b0 = data[0];
+ Byte b1 = data[1];
+ data[0] = data[3];
+ data[1] = data[2];
+ data[2] = b1;
+ data[3] = b0;
+ data += kStep;
+ }
+ while (data != end);
+
+ return size;
+}
+
+REGISTER_FILTER_CREATE(CreateFilter2, CByteSwap2())
+REGISTER_FILTER_CREATE(CreateFilter4, CByteSwap4())
+
+REGISTER_CODECS_VAR
+{
+ REGISTER_FILTER_ITEM(CreateFilter2, CreateFilter2, 0x20302, "Swap2"),
+ REGISTER_FILTER_ITEM(CreateFilter4, CreateFilter4, 0x20304, "Swap4")
+};
+
+REGISTER_CODECS(ByteSwap)
+
+}}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/CodecExports.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/CodecExports.cpp
new file mode 100644
index 000000000..7be496c24
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/CodecExports.cpp
@@ -0,0 +1,344 @@
+// CodecExports.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/CpuArch.h"
+
+#include "../../Common/ComTry.h"
+#include "../../Common/MyCom.h"
+
+#include "../../Windows/Defs.h"
+
+#include "../ICoder.h"
+
+#include "../Common/RegisterCodec.h"
+
+extern unsigned g_NumCodecs;
+extern const CCodecInfo *g_Codecs[];
+
+extern unsigned g_NumHashers;
+extern const CHasherInfo *g_Hashers[];
+
+static void SetPropFromAscii(const char *s, PROPVARIANT *prop) throw()
+{
+ UINT len = (UINT)strlen(s);
+ BSTR 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) throw()
+{
+ if ((value->bstrVal = ::SysAllocStringByteLen((const char *)&guid, sizeof(guid))) != NULL)
+ value->vt = VT_BSTR;
+ return S_OK;
+}
+
+static HRESULT MethodToClassID(UInt16 typeId, CMethodId id, PROPVARIANT *value) throw()
+{
+ GUID clsId;
+ 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, bool isCoder2, bool isFilter, bool &encode, int &index) throw()
+{
+ index = -1;
+ if (clsid->Data1 != k_7zip_GUID_Data1 ||
+ clsid->Data2 != k_7zip_GUID_Data2)
+ return S_OK;
+
+ encode = true;
+
+ 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 : !codec.CreateDecoder)
+ || (isFilter ? !codec.IsFilter : codec.IsFilter))
+ continue;
+
+ if (codec.NumStreams == 1 ? isCoder2 : !isCoder2)
+ return E_NOINTERFACE;
+
+ index = i;
+ return S_OK;
+ }
+
+ return S_OK;
+}
+
+static HRESULT CreateCoderMain(unsigned index, bool encode, void **coder)
+{
+ COM_TRY_BEGIN
+
+ const CCodecInfo &codec = *g_Codecs[index];
+
+ void *c;
+ if (encode)
+ c = codec.CreateEncoder();
+ else
+ c = codec.CreateDecoder();
+
+ if (c)
+ {
+ IUnknown *unk;
+ if (codec.IsFilter)
+ unk = (IUnknown *)(ICompressFilter *)c;
+ else if (codec.NumStreams != 1)
+ unk = (IUnknown *)(ICompressCoder2 *)c;
+ else
+ 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)
+{
+ *outObject = NULL;
+
+ bool isFilter = false;
+ bool isCoder2 = false;
+ bool isCoder = (*iid == IID_ICompressCoder) != 0;
+ 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);
+ if (res != S_OK)
+ return res;
+ if (codecIndex < 0)
+ return CLASS_E_CLASSNOTAVAILABLE;
+
+ return CreateCoderMain(codecIndex, encode, outObject);
+}
+
+STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value)
+{
+ ::VariantClear((VARIANTARG *)value);
+ const CCodecInfo &codec = *g_Codecs[codecIndex];
+ switch (propID)
+ {
+ case NMethodPropID::kID:
+ value->uhVal.QuadPart = (UInt64)codec.Id;
+ value->vt = VT_UI8;
+ break;
+ case NMethodPropID::kName:
+ SetPropFromAscii(codec.Name, value);
+ break;
+ case NMethodPropID::kDecoder:
+ if (codec.CreateDecoder)
+ return MethodToClassID(k_7zip_GUID_Data3_Decoder, codec.Id, value);
+ break;
+ case NMethodPropID::kEncoder:
+ if (codec.CreateEncoder)
+ 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::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.EncoderFlags;
+ }
+ break;
+ */
+ }
+ return S_OK;
+}
+
+STDAPI GetNumberOfMethods(UINT32 *numCodecs)
+{
+ *numCodecs = g_NumCodecs;
+ return S_OK;
+}
+
+
+// ---------- Hashers ----------
+
+static int FindHasherClassId(const GUID *clsid) throw()
+{
+ 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);
+ for (unsigned i = 0; i < g_NumCodecs; i++)
+ if (id == g_Hashers[i]->Id)
+ return i;
+ return -1;
+}
+
+static HRESULT CreateHasher2(UInt32 index, IHasher **hasher)
+{
+ COM_TRY_BEGIN
+ *hasher = g_Hashers[index]->CreateHasher();
+ if (*hasher)
+ (*hasher)->AddRef();
+ return S_OK;
+ COM_TRY_END
+}
+
+STDAPI CreateHasher(const GUID *clsid, IHasher **outObject)
+{
+ COM_TRY_BEGIN
+ *outObject = 0;
+ int index = FindHasherClassId(clsid);
+ if (index < 0)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ return CreateHasher2(index, outObject);
+ COM_TRY_END
+}
+
+STDAPI GetHasherProp(UInt32 codecIndex, PROPID propID, PROPVARIANT *value)
+{
+ ::VariantClear((VARIANTARG *)value);
+ const CHasherInfo &codec = *g_Hashers[codecIndex];
+ switch (propID)
+ {
+ case NMethodPropID::kID:
+ value->uhVal.QuadPart = (UInt64)codec.Id;
+ value->vt = VT_UI8;
+ break;
+ case NMethodPropID::kName:
+ SetPropFromAscii(codec.Name, value);
+ break;
+ case NMethodPropID::kEncoder:
+ if (codec.CreateHasher)
+ return MethodToClassID(k_7zip_GUID_Data3_Hasher, codec.Id, value);
+ break;
+ case NMethodPropID::kDigestSize:
+ value->ulVal = (ULONG)codec.DigestSize;
+ value->vt = VT_UI4;
+ break;
+ }
+ return S_OK;
+}
+
+class CHashers:
+ public IHashers,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(IHashers)
+
+ STDMETHOD_(UInt32, GetNumHashers)();
+ STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher);
+};
+
+STDAPI GetHashers(IHashers **hashers)
+{
+ COM_TRY_BEGIN
+ *hashers = new CHashers;
+ if (*hashers)
+ (*hashers)->AddRef();
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP_(UInt32) CHashers::GetNumHashers()
+{
+ return g_NumHashers;
+}
+
+STDMETHODIMP CHashers::GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ return ::GetHasherProp(index, propID, value);
+}
+
+STDMETHODIMP CHashers::CreateHasher(UInt32 index, IHasher **hasher)
+{
+ return ::CreateHasher2(index, hasher);
+}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/CopyCoder.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/CopyCoder.cpp
new file mode 100644
index 000000000..89b523765
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/CopyCoder.cpp
@@ -0,0 +1,120 @@
+// Compress/CopyCoder.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/Alloc.h"
+
+#include "CopyCoder.h"
+
+namespace NCompress {
+
+static const UInt32 kBufSize = 1 << 17;
+
+CCopyCoder::~CCopyCoder()
+{
+ ::MidFree(_buf);
+}
+
+STDMETHODIMP CCopyCoder::SetFinishMode(UInt32 /* finishMode */)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 * /* inSize */, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ if (!_buf)
+ {
+ _buf = (Byte *)::MidAlloc(kBufSize);
+ if (!_buf)
+ return E_OUTOFMEMORY;
+ }
+
+ TotalSize = 0;
+
+ for (;;)
+ {
+ UInt32 size = kBufSize;
+ if (outSize && size > *outSize - TotalSize)
+ size = (UInt32)(*outSize - TotalSize);
+ if (size == 0)
+ return S_OK;
+
+ HRESULT readRes = inStream->Read(_buf, size, &size);
+
+ if (size == 0)
+ return readRes;
+
+ if (outStream)
+ {
+ 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);
+ }
+ 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;
+ return S_OK;
+}
+
+HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress)
+{
+ CMyComPtr<ICompressCoder> copyCoder = new CCopyCoder;
+ return copyCoder->Code(inStream, outStream, NULL, NULL, progress);
+}
+
+HRESULT CopyStream_ExactSize(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt64 size, ICompressProgressInfo *progress)
+{
+ NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
+ CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
+ RINOK(copyCoder->Code(inStream, outStream, NULL, &size, progress));
+ return copyCoderSpec->TotalSize == size ? S_OK : E_FAIL;
+}
+
+}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/CopyCoder.h b/other-licenses/7zstub/src/CPP/7zip/Compress/CopyCoder.h
new file mode 100644
index 000000000..b2fa491e0
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/CopyCoder.h
@@ -0,0 +1,49 @@
+// Compress/CopyCoder.h
+
+#ifndef __COMPRESS_COPY_CODER_H
+#define __COMPRESS_COPY_CODER_H
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+
+namespace NCompress {
+
+class CCopyCoder:
+ public ICompressCoder,
+ public ICompressSetInStream,
+ public ISequentialInStream,
+ public ICompressSetFinishMode,
+ public ICompressGetInStreamProcessedSize,
+ public CMyUnknownImp
+{
+ Byte *_buf;
+ CMyComPtr<ISequentialInStream> _inStream;
+public:
+ UInt64 TotalSize;
+
+ CCopyCoder(): _buf(0), TotalSize(0) {};
+ ~CCopyCoder();
+
+ MY_UNKNOWN_IMP5(
+ ICompressCoder,
+ ICompressSetInStream,
+ ISequentialInStream,
+ ICompressSetFinishMode,
+ 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(SetFinishMode)(UInt32 finishMode);
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+};
+
+HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress);
+HRESULT CopyStream_ExactSize(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt64 size, ICompressProgressInfo *progress);
+
+}
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/CopyRegister.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/CopyRegister.cpp
new file mode 100644
index 000000000..1c59fe0c0
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/CopyRegister.cpp
@@ -0,0 +1,15 @@
+// CopyRegister.cpp
+
+#include "StdAfx.h"
+
+#include "../Common/RegisterCodec.h"
+
+#include "CopyCoder.h"
+
+namespace NCompress {
+
+REGISTER_CODEC_CREATE(CreateCodec, CCopyCoder())
+
+REGISTER_CODEC_2(Copy, CreateCodec, CreateCodec, 0, "Copy")
+
+}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/DeltaFilter.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/DeltaFilter.cpp
new file mode 100644
index 000000000..cdbd33d4c
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/DeltaFilter.cpp
@@ -0,0 +1,128 @@
+// DeltaFilter.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/Delta.h"
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+
+#include "../Common/RegisterCodec.h"
+
+namespace NCompress {
+namespace NDelta {
+
+struct CDelta
+{
+ unsigned _delta;
+ Byte _state[DELTA_STATE_SIZE];
+
+ CDelta(): _delta(1) {}
+ void DeltaInit() { Delta_Init(_state); }
+};
+
+
+#ifndef EXTRACT_ONLY
+
+class CEncoder:
+ public ICompressFilter,
+ public ICompressSetCoderProperties,
+ public ICompressWriteCoderProperties,
+ CDelta,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP3(ICompressFilter, ICompressSetCoderProperties, ICompressWriteCoderProperties)
+ INTERFACE_ICompressFilter(;)
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+};
+
+STDMETHODIMP CEncoder::Init()
+{
+ DeltaInit();
+ return S_OK;
+}
+
+STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size)
+{
+ Delta_Encode(_state, _delta, data, size);
+ return size;
+}
+
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
+{
+ UInt32 delta = _delta;
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ const PROPVARIANT &prop = props[i];
+ PROPID propID = propIDs[i];
+ if (propID >= NCoderPropID::kReduceSize)
+ continue;
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ switch (propID)
+ {
+ case NCoderPropID::kDefaultProp:
+ delta = (UInt32)prop.ulVal;
+ if (delta < 1 || delta > 256)
+ return E_INVALIDARG;
+ break;
+ case NCoderPropID::kNumThreads: break;
+ case NCoderPropID::kLevel: break;
+ default: return E_INVALIDARG;
+ }
+ }
+ _delta = delta;
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ Byte prop = (Byte)(_delta - 1);
+ return outStream->Write(&prop, 1, NULL);
+}
+
+#endif
+
+
+class CDecoder:
+ public ICompressFilter,
+ public ICompressSetDecoderProperties2,
+ CDelta,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP2(ICompressFilter, ICompressSetDecoderProperties2)
+ INTERFACE_ICompressFilter(;)
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+};
+
+STDMETHODIMP CDecoder::Init()
+{
+ DeltaInit();
+ return S_OK;
+}
+
+STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)
+{
+ Delta_Decode(_state, _delta, data, size);
+ return size;
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)
+{
+ if (size != 1)
+ return E_INVALIDARG;
+ _delta = (unsigned)props[0] + 1;
+ return S_OK;
+}
+
+
+REGISTER_FILTER_E(Delta,
+ CDecoder(),
+ CEncoder(),
+ 3, "Delta")
+
+}}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/Lzma2Decoder.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/Lzma2Decoder.cpp
new file mode 100644
index 000000000..bb631c5c5
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/Lzma2Decoder.cpp
@@ -0,0 +1,265 @@
+// Lzma2Decoder.cpp
+
+#include "StdAfx.h"
+
+// #include <stdio.h>
+
+#include "../../../C/Alloc.h"
+// #include "../../../C/CpuTicks.h"
+
+#include "../Common/StreamUtils.h"
+
+#include "Lzma2Decoder.h"
+
+namespace NCompress {
+namespace NLzma2 {
+
+CDecoder::CDecoder():
+ _dec(NULL)
+ , _inProcessed(0)
+ , _prop(0xFF)
+ , _finishMode(false)
+ , _inBufSize(1 << 20)
+ , _outStep(1 << 20)
+ #ifndef _7ZIP_ST
+ , _tryMt(1)
+ , _numThreads(1)
+ , _memUsage((UInt64)(sizeof(size_t)) << 28)
+ #endif
+{}
+
+CDecoder::~CDecoder()
+{
+ if (_dec)
+ Lzma2DecMt_Destroy(_dec);
+}
+
+STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSize = size; return S_OK; }
+STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outStep = size; return S_OK; }
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)
+{
+ if (size != 1)
+ return E_NOTIMPL;
+ if (prop[0] > 40)
+ return E_NOTIMPL;
+ _prop = prop[0];
+ return S_OK;
+}
+
+
+STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode)
+{
+ _finishMode = (finishMode != 0);
+ return S_OK;
+}
+
+
+
+#ifndef _7ZIP_ST
+
+static UInt64 Get_ExpectedBlockSize_From_Dict(UInt32 dictSize)
+{
+ const UInt32 kMinSize = (UInt32)1 << 20;
+ const UInt32 kMaxSize = (UInt32)1 << 28;
+ UInt64 blockSize = (UInt64)dictSize << 2;
+ if (blockSize < kMinSize) blockSize = kMinSize;
+ if (blockSize > kMaxSize) blockSize = kMaxSize;
+ if (blockSize < dictSize) blockSize = dictSize;
+ blockSize += (kMinSize - 1);
+ blockSize &= ~(UInt64)(kMinSize - 1);
+ return blockSize;
+}
+
+#define LZMA2_DIC_SIZE_FROM_PROP_FULL(p) ((p) == 40 ? 0xFFFFFFFF : (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)))
+
+#endif
+
+#define RET_IF_WRAP_ERROR_CONFIRMED(wrapRes, sRes, sResErrorCode) \
+ if (wrapRes != S_OK && sRes == sResErrorCode) return wrapRes;
+
+#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
+ if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
+{
+ _inProcessed = 0;
+
+ if (!_dec)
+ {
+ _dec = Lzma2DecMt_Create(
+ // &g_AlignedAlloc,
+ &g_Alloc,
+ &g_MidAlloc);
+ if (!_dec)
+ return E_OUTOFMEMORY;
+ }
+
+ CLzma2DecMtProps props;
+ Lzma2DecMtProps_Init(&props);
+
+ props.inBufSize_ST = _inBufSize;
+ props.outStep_ST = _outStep;
+
+ #ifndef _7ZIP_ST
+ {
+ props.numThreads = 1;
+ UInt32 numThreads = _numThreads;
+
+ if (_tryMt && numThreads >= 1)
+ {
+ UInt64 useLimit = _memUsage;
+ UInt32 dictSize = LZMA2_DIC_SIZE_FROM_PROP_FULL(_prop);
+ UInt64 expectedBlockSize64 = Get_ExpectedBlockSize_From_Dict(dictSize);
+ size_t expectedBlockSize = (size_t)expectedBlockSize64;
+ size_t inBlockMax = expectedBlockSize + expectedBlockSize / 16;
+ if (expectedBlockSize == expectedBlockSize64 && inBlockMax >= expectedBlockSize)
+ {
+ props.outBlockMax = expectedBlockSize;
+ props.inBlockMax = inBlockMax;
+ const size_t kOverheadSize = props.inBufSize_MT + (1 << 16);
+ UInt64 okThreads = useLimit / (props.outBlockMax + props.inBlockMax + kOverheadSize);
+ if (numThreads > okThreads)
+ numThreads = (UInt32)okThreads;
+ if (numThreads == 0)
+ numThreads = 1;
+ props.numThreads = numThreads;
+ }
+ }
+ }
+ #endif
+
+ CSeqInStreamWrap inWrap;
+ CSeqOutStreamWrap outWrap;
+ CCompressProgressWrap progressWrap;
+
+ inWrap.Init(inStream);
+ outWrap.Init(outStream);
+ progressWrap.Init(progress);
+
+ SRes res;
+
+ UInt64 inProcessed = 0;
+ int isMT = False;
+
+ #ifndef _7ZIP_ST
+ isMT = _tryMt;
+ #endif
+
+ // UInt64 cpuTicks = GetCpuTicks();
+
+ res = Lzma2DecMt_Decode(_dec, _prop, &props,
+ &outWrap.vt, outSize, _finishMode,
+ &inWrap.vt,
+ &inProcessed,
+ &isMT,
+ progress ? &progressWrap.vt : NULL);
+
+ /*
+ cpuTicks = GetCpuTicks() - cpuTicks;
+ printf("\n ticks = %10I64u\n", cpuTicks / 1000000);
+ */
+
+
+ #ifndef _7ZIP_ST
+ /* we reset _tryMt, only if p->props.numThreads was changed */
+ if (props.numThreads > 1)
+ _tryMt = isMT;
+ #endif
+
+ _inProcessed = inProcessed;
+
+ RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
+ RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
+ RET_IF_WRAP_ERROR_CONFIRMED(inWrap.Res, res, SZ_ERROR_READ)
+
+ if (res == SZ_OK && _finishMode)
+ {
+ if (inSize && *inSize != inProcessed)
+ res = SZ_ERROR_DATA;
+ if (outSize && *outSize != outWrap.Processed)
+ res = SZ_ERROR_DATA;
+ }
+
+ return SResToHRESULT(res);
+}
+
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ *value = _inProcessed;
+ return S_OK;
+}
+
+
+#ifndef _7ZIP_ST
+
+STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads)
+{
+ _numThreads = numThreads;
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::SetMemLimit(UInt64 memUsage)
+{
+ _memUsage = memUsage;
+ return S_OK;
+}
+
+#endif
+
+
+#ifndef NO_READ_FROM_CODER
+
+STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
+{
+ CLzma2DecMtProps props;
+ Lzma2DecMtProps_Init(&props);
+ props.inBufSize_ST = _inBufSize;
+ props.outStep_ST = _outStep;
+
+ _inProcessed = 0;
+
+ if (!_dec)
+ {
+ _dec = Lzma2DecMt_Create(&g_AlignedAlloc, &g_MidAlloc);
+ if (!_dec)
+ return E_OUTOFMEMORY;
+ }
+
+ _inWrap.Init(_inStream);
+
+ SRes res = Lzma2DecMt_Init(_dec, _prop, &props, outSize, _finishMode, &_inWrap.vt);
+
+ if (res != SZ_OK)
+ return SResToHRESULT(res);
+ return S_OK;
+}
+
+
+STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; }
+STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; }
+
+
+STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize)
+ *processedSize = 0;
+
+ size_t size2 = size;
+ UInt64 inProcessed = 0;
+
+ SRes res = Lzma2DecMt_Read(_dec, (Byte *)data, &size2, &inProcessed);
+
+ _inProcessed += inProcessed;
+ if (processedSize)
+ *processedSize = (UInt32)size2;
+ if (res != SZ_OK)
+ return SResToHRESULT(res);
+ return S_OK;
+}
+
+#endif
+
+}}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/Lzma2Decoder.h b/other-licenses/7zstub/src/CPP/7zip/Compress/Lzma2Decoder.h
new file mode 100644
index 000000000..b56488e0d
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/Lzma2Decoder.h
@@ -0,0 +1,96 @@
+// Lzma2Decoder.h
+
+#ifndef __LZMA2_DECODER_H
+#define __LZMA2_DECODER_H
+
+#include "../../../C/Lzma2DecMt.h"
+
+#include "../Common/CWrappers.h"
+
+namespace NCompress {
+namespace NLzma2 {
+
+class CDecoder:
+ public ICompressCoder,
+ public ICompressSetDecoderProperties2,
+ public ICompressSetFinishMode,
+ public ICompressGetInStreamProcessedSize,
+ public ICompressSetBufSize,
+
+ #ifndef NO_READ_FROM_CODER
+ public ICompressSetInStream,
+ public ICompressSetOutStreamSize,
+ public ISequentialInStream,
+ #endif
+
+ #ifndef _7ZIP_ST
+ public ICompressSetCoderMt,
+ public ICompressSetMemLimit,
+ #endif
+
+ public CMyUnknownImp
+{
+ CLzma2DecMtHandle _dec;
+ UInt64 _inProcessed;
+ Byte _prop;
+ int _finishMode;
+ UInt32 _inBufSize;
+ UInt32 _outStep;
+
+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_QUERYINTERFACE_ENTRY(ICompressSetInStream)
+ MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize)
+ MY_QUERYINTERFACE_ENTRY(ISequentialInStream)
+ #endif
+
+ #ifndef _7ZIP_ST
+ MY_QUERYINTERFACE_ENTRY(ICompressSetCoderMt)
+ MY_QUERYINTERFACE_ENTRY(ICompressSetMemLimit)
+ #endif
+
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+
+ 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);
+
+ #ifndef _7ZIP_ST
+private:
+ int _tryMt;
+ UInt32 _numThreads;
+ UInt64 _memUsage;
+public:
+ STDMETHOD(SetNumberOfThreads)(UInt32 numThreads);
+ STDMETHOD(SetMemLimit)(UInt64 memUsage);
+ #endif
+
+ #ifndef NO_READ_FROM_CODER
+private:
+ CMyComPtr<ISequentialInStream> _inStream;
+ CSeqInStreamWrap _inWrap;
+public:
+ STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
+ STDMETHOD(SetInStream)(ISequentialInStream *inStream);
+ STDMETHOD(ReleaseInStream)();
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ #endif
+
+ CDecoder();
+ virtual ~CDecoder();
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/Lzma2Encoder.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/Lzma2Encoder.cpp
new file mode 100644
index 000000000..18f7d029d
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/Lzma2Encoder.cpp
@@ -0,0 +1,122 @@
+// Lzma2Encoder.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/Alloc.h"
+
+#include "../Common/CWrappers.h"
+#include "../Common/StreamUtils.h"
+
+#include "Lzma2Encoder.h"
+
+namespace NCompress {
+
+namespace NLzma {
+
+HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep);
+
+}
+
+namespace NLzma2 {
+
+CEncoder::CEncoder()
+{
+ _encoder = NULL;
+ _encoder = Lzma2Enc_Create(&g_AlignedAlloc, &g_BigAlloc);
+ if (!_encoder)
+ throw 1;
+}
+
+CEncoder::~CEncoder()
+{
+ if (_encoder)
+ Lzma2Enc_Destroy(_encoder);
+}
+
+
+HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props)
+{
+ switch (propID)
+ {
+ case NCoderPropID::kBlockSize:
+ {
+ if (prop.vt == VT_UI4)
+ lzma2Props.blockSize = prop.ulVal;
+ else if (prop.vt == VT_UI8)
+ lzma2Props.blockSize = prop.uhVal.QuadPart;
+ else
+ return E_INVALIDARG;
+ break;
+ }
+ case NCoderPropID::kNumThreads:
+ if (prop.vt != VT_UI4) return E_INVALIDARG; lzma2Props.numTotalThreads = (int)(prop.ulVal); break;
+ default:
+ RINOK(NLzma::SetLzmaProp(propID, prop, lzma2Props.lzmaProps));
+ }
+ return S_OK;
+}
+
+
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
+ const PROPVARIANT *coderProps, UInt32 numProps)
+{
+ CLzma2EncProps lzma2Props;
+ Lzma2EncProps_Init(&lzma2Props);
+
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ RINOK(SetLzma2Prop(propIDs[i], coderProps[i], lzma2Props));
+ }
+ return SResToHRESULT(Lzma2Enc_SetProps(_encoder, &lzma2Props));
+}
+
+
+STDMETHODIMP CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs,
+ const PROPVARIANT *coderProps, UInt32 numProps)
+{
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ const PROPVARIANT &prop = coderProps[i];
+ PROPID propID = propIDs[i];
+ if (propID == NCoderPropID::kExpectedDataSize)
+ if (prop.vt == VT_UI8)
+ Lzma2Enc_SetDataSize(_encoder, prop.uhVal.QuadPart);
+ }
+ return S_OK;
+}
+
+
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ Byte prop = Lzma2Enc_WriteProperties(_encoder);
+ return WriteStream(outStream, &prop, 1);
+}
+
+
+#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
+ if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
+
+STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
+{
+ CSeqInStreamWrap inWrap;
+ CSeqOutStreamWrap outWrap;
+ CCompressProgressWrap progressWrap;
+
+ inWrap.Init(inStream);
+ outWrap.Init(outStream);
+ progressWrap.Init(progress);
+
+ SRes res = Lzma2Enc_Encode2(_encoder,
+ &outWrap.vt, NULL, NULL,
+ &inWrap.vt, NULL, 0,
+ progress ? &progressWrap.vt : NULL);
+
+ RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ)
+ RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
+ RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
+
+ return SResToHRESULT(res);
+}
+
+}}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/Lzma2Encoder.h b/other-licenses/7zstub/src/CPP/7zip/Compress/Lzma2Encoder.h
new file mode 100644
index 000000000..6539e73ac
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/Lzma2Encoder.h
@@ -0,0 +1,42 @@
+// Lzma2Encoder.h
+
+#ifndef __LZMA2_ENCODER_H
+#define __LZMA2_ENCODER_H
+
+#include "../../../C/Lzma2Enc.h"
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+
+namespace NCompress {
+namespace NLzma2 {
+
+class CEncoder:
+ public ICompressCoder,
+ public ICompressSetCoderProperties,
+ public ICompressWriteCoderProperties,
+ public ICompressSetCoderPropertiesOpt,
+ public CMyUnknownImp
+{
+ CLzma2EncHandle _encoder;
+public:
+ MY_UNKNOWN_IMP4(
+ ICompressCoder,
+ ICompressSetCoderProperties,
+ ICompressWriteCoderProperties,
+ ICompressSetCoderPropertiesOpt)
+
+ STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+ STDMETHOD(SetCoderPropertiesOpt)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+
+ CEncoder();
+ virtual ~CEncoder();
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/Lzma2Register.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/Lzma2Register.cpp
new file mode 100644
index 000000000..436710563
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/Lzma2Register.cpp
@@ -0,0 +1,22 @@
+// Lzma2Register.cpp
+
+#include "StdAfx.h"
+
+#include "../Common/RegisterCodec.h"
+
+#include "Lzma2Decoder.h"
+
+#ifndef EXTRACT_ONLY
+#include "Lzma2Encoder.h"
+#endif
+
+namespace NCompress {
+namespace NLzma2 {
+
+REGISTER_CODEC_E(LZMA2,
+ CDecoder(),
+ CEncoder(),
+ 0x21,
+ "LZMA2")
+
+}}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/LzmaDecoder.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/LzmaDecoder.cpp
new file mode 100644
index 000000000..b6a8d3fbd
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/LzmaDecoder.cpp
@@ -0,0 +1,343 @@
+// LzmaDecoder.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/Alloc.h"
+
+#include "../Common/StreamUtils.h"
+
+#include "LzmaDecoder.h"
+
+static HRESULT SResToHRESULT(SRes res)
+{
+ switch (res)
+ {
+ case SZ_OK: return S_OK;
+ case SZ_ERROR_MEM: return E_OUTOFMEMORY;
+ case SZ_ERROR_PARAM: return E_INVALIDARG;
+ case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL;
+ case SZ_ERROR_DATA: return S_FALSE;
+ }
+ return E_FAIL;
+}
+
+namespace NCompress {
+namespace NLzma {
+
+CDecoder::CDecoder():
+ _inBuf(NULL),
+ _lzmaStatus(LZMA_STATUS_NOT_SPECIFIED),
+ FinishStream(false),
+ _propsWereSet(false),
+ _outSizeDefined(false),
+ _outStep(1 << 20),
+ _inBufSize(0),
+ _inBufSizeNew(1 << 20)
+{
+ _inProcessed = 0;
+ _inPos = _inLim = 0;
+
+ /*
+ AlignOffsetAlloc_CreateVTable(&_alloc);
+ _alloc.numAlignBits = 7;
+ _alloc.offset = 0;
+ */
+ LzmaDec_Construct(&_state);
+}
+
+CDecoder::~CDecoder()
+{
+ LzmaDec_Free(&_state, &g_AlignedAlloc); // &_alloc.vt
+ MyFree(_inBuf);
+}
+
+STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSizeNew = size; return S_OK; }
+STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outStep = size; return S_OK; }
+
+HRESULT CDecoder::CreateInputBuffer()
+{
+ if (!_inBuf || _inBufSizeNew != _inBufSize)
+ {
+ MyFree(_inBuf);
+ _inBufSize = 0;
+ _inBuf = (Byte *)MyAlloc(_inBufSizeNew);
+ if (!_inBuf)
+ return E_OUTOFMEMORY;
+ _inBufSize = _inBufSizeNew;
+ }
+ return S_OK;
+}
+
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)
+{
+ RINOK(SResToHRESULT(LzmaDec_Allocate(&_state, prop, size, &g_AlignedAlloc))) // &_alloc.vt
+ _propsWereSet = true;
+ return CreateInputBuffer();
+}
+
+
+void CDecoder::SetOutStreamSizeResume(const UInt64 *outSize)
+{
+ _outSizeDefined = (outSize != NULL);
+ _outSize = 0;
+ if (_outSizeDefined)
+ _outSize = *outSize;
+ _outProcessed = 0;
+ _lzmaStatus = LZMA_STATUS_NOT_SPECIFIED;
+
+ LzmaDec_Init(&_state);
+}
+
+
+STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
+{
+ _inProcessed = 0;
+ _inPos = _inLim = 0;
+ SetOutStreamSizeResume(outSize);
+ return S_OK;
+}
+
+
+STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode)
+{
+ FinishStream = (finishMode != 0);
+ return S_OK;
+}
+
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ *value = _inProcessed;
+ return S_OK;
+}
+
+
+HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress)
+{
+ if (!_inBuf || !_propsWereSet)
+ return S_FALSE;
+
+ const UInt64 startInProgress = _inProcessed;
+ SizeT wrPos = _state.dicPos;
+ HRESULT readRes = S_OK;
+
+ for (;;)
+ {
+ if (_inPos == _inLim && readRes == S_OK)
+ {
+ _inPos = _inLim = 0;
+ readRes = inStream->Read(_inBuf, _inBufSize, &_inLim);
+ }
+
+ const SizeT dicPos = _state.dicPos;
+ SizeT size;
+ {
+ SizeT next = _state.dicBufSize;
+ if (next - wrPos > _outStep)
+ next = wrPos + _outStep;
+ size = next - dicPos;
+ }
+
+ ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
+ if (_outSizeDefined)
+ {
+ const UInt64 rem = _outSize - _outProcessed;
+ if (size >= rem)
+ {
+ size = (SizeT)rem;
+ if (FinishStream)
+ finishMode = LZMA_FINISH_END;
+ }
+ }
+
+ SizeT inProcessed = _inLim - _inPos;
+ ELzmaStatus status;
+
+ SRes res = LzmaDec_DecodeToDic(&_state, dicPos + size, _inBuf + _inPos, &inProcessed, finishMode, &status);
+
+ _lzmaStatus = status;
+ _inPos += (UInt32)inProcessed;
+ _inProcessed += inProcessed;
+ const SizeT outProcessed = _state.dicPos - dicPos;
+ _outProcessed += outProcessed;
+
+ // we check for LZMA_STATUS_NEEDS_MORE_INPUT to allow RangeCoder initialization, if (_outSizeDefined && _outSize == 0)
+ bool outFinished = (_outSizeDefined && _outProcessed >= _outSize);
+
+ bool needStop = (res != 0
+ || (inProcessed == 0 && outProcessed == 0)
+ || status == LZMA_STATUS_FINISHED_WITH_MARK
+ || (outFinished && status != LZMA_STATUS_NEEDS_MORE_INPUT));
+
+ if (needStop || outProcessed >= size)
+ {
+ HRESULT res2 = WriteStream(outStream, _state.dic + wrPos, _state.dicPos - wrPos);
+
+ if (_state.dicPos == _state.dicBufSize)
+ _state.dicPos = 0;
+ wrPos = _state.dicPos;
+
+ RINOK(res2);
+
+ if (needStop)
+ {
+ if (res != 0)
+ return S_FALSE;
+
+ if (status == LZMA_STATUS_FINISHED_WITH_MARK)
+ {
+ if (FinishStream)
+ if (_outSizeDefined && _outSize != _outProcessed)
+ return S_FALSE;
+ return readRes;
+ }
+
+ if (outFinished && status != LZMA_STATUS_NEEDS_MORE_INPUT)
+ if (!FinishStream || status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
+ return readRes;
+
+ return S_FALSE;
+ }
+ }
+
+ if (progress)
+ {
+ const UInt64 inSize = _inProcessed - startInProgress;
+ RINOK(progress->SetRatioInfo(&inSize, &_outProcessed));
+ }
+ }
+}
+
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
+{
+ if (!_inBuf)
+ return E_INVALIDARG;
+ SetOutStreamSize(outSize);
+ HRESULT res = CodeSpec(inStream, outStream, progress);
+ if (res == S_OK)
+ if (FinishStream && inSize && *inSize != _inProcessed)
+ res = S_FALSE;
+ return res;
+}
+
+
+#ifndef NO_READ_FROM_CODER
+
+STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; }
+STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; }
+
+
+STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize)
+ *processedSize = 0;
+
+ ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
+ if (_outSizeDefined)
+ {
+ const UInt64 rem = _outSize - _outProcessed;
+ if (size >= rem)
+ {
+ size = (UInt32)rem;
+ if (FinishStream)
+ finishMode = LZMA_FINISH_END;
+ }
+ }
+
+ HRESULT readRes = S_OK;
+
+ for (;;)
+ {
+ if (_inPos == _inLim && readRes == S_OK)
+ {
+ _inPos = _inLim = 0;
+ readRes = _inStream->Read(_inBuf, _inBufSize, &_inLim);
+ }
+
+ SizeT inProcessed = _inLim - _inPos;
+ SizeT outProcessed = size;
+ ELzmaStatus status;
+
+ SRes res = LzmaDec_DecodeToBuf(&_state, (Byte *)data, &outProcessed,
+ _inBuf + _inPos, &inProcessed, finishMode, &status);
+
+ _lzmaStatus = status;
+ _inPos += (UInt32)inProcessed;
+ _inProcessed += inProcessed;
+ _outProcessed += outProcessed;
+ size -= (UInt32)outProcessed;
+ data = (Byte *)data + outProcessed;
+ if (processedSize)
+ *processedSize += (UInt32)outProcessed;
+
+ if (res != 0)
+ return S_FALSE;
+
+ /*
+ if (status == LZMA_STATUS_FINISHED_WITH_MARK)
+ return readRes;
+
+ if (size == 0 && status != LZMA_STATUS_NEEDS_MORE_INPUT)
+ {
+ if (FinishStream
+ && _outSizeDefined && _outProcessed >= _outSize
+ && status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
+ return S_FALSE;
+ return readRes;
+ }
+ */
+
+ if (inProcessed == 0 && outProcessed == 0)
+ return readRes;
+ }
+}
+
+
+HRESULT CDecoder::CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress)
+{
+ SetOutStreamSizeResume(outSize);
+ return CodeSpec(_inStream, outStream, progress);
+}
+
+
+HRESULT CDecoder::ReadFromInputStream(void *data, UInt32 size, UInt32 *processedSize)
+{
+ RINOK(CreateInputBuffer());
+
+ if (processedSize)
+ *processedSize = 0;
+
+ HRESULT readRes = S_OK;
+
+ while (size != 0)
+ {
+ if (_inPos == _inLim)
+ {
+ _inPos = _inLim = 0;
+ if (readRes == S_OK)
+ readRes = _inStream->Read(_inBuf, _inBufSize, &_inLim);
+ if (_inLim == 0)
+ break;
+ }
+
+ UInt32 cur = _inLim - _inPos;
+ if (cur > size)
+ cur = size;
+ memcpy(data, _inBuf + _inPos, cur);
+ _inPos += cur;
+ _inProcessed += cur;
+ size -= cur;
+ data = (Byte *)data + cur;
+ if (processedSize)
+ *processedSize += cur;
+ }
+
+ return readRes;
+}
+
+#endif
+
+}}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/LzmaDecoder.h b/other-licenses/7zstub/src/CPP/7zip/Compress/LzmaDecoder.h
new file mode 100644
index 000000000..08b7c1bc3
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/LzmaDecoder.h
@@ -0,0 +1,113 @@
+// LzmaDecoder.h
+
+#ifndef __LZMA_DECODER_H
+#define __LZMA_DECODER_H
+
+// #include "../../../C/Alloc.h"
+#include "../../../C/LzmaDec.h"
+
+#include "../../Common/MyCom.h"
+#include "../ICoder.h"
+
+namespace NCompress {
+namespace NLzma {
+
+class CDecoder:
+ public ICompressCoder,
+ public ICompressSetDecoderProperties2,
+ public ICompressSetFinishMode,
+ public ICompressGetInStreamProcessedSize,
+ public ICompressSetBufSize,
+ #ifndef NO_READ_FROM_CODER
+ public ICompressSetInStream,
+ public ICompressSetOutStreamSize,
+ public ISequentialInStream,
+ #endif
+ public CMyUnknownImp
+{
+ Byte *_inBuf;
+ UInt32 _inPos;
+ UInt32 _inLim;
+
+ ELzmaStatus _lzmaStatus;
+
+public:
+ bool FinishStream; // set it before decoding, if you need to decode full LZMA stream
+
+private:
+ bool _propsWereSet;
+ bool _outSizeDefined;
+ UInt64 _outSize;
+ UInt64 _inProcessed;
+ UInt64 _outProcessed;
+
+ UInt32 _outStep;
+ UInt32 _inBufSize;
+ UInt32 _inBufSizeNew;
+
+ // CAlignOffsetAlloc _alloc;
+
+ CLzmaDec _state;
+
+ HRESULT CreateInputBuffer();
+ HRESULT CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress);
+ void SetOutStreamSizeResume(const UInt64 *outSize);
+
+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_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(SetDecoderProperties2)(const Byte *data, UInt32 size);
+ STDMETHOD(SetFinishMode)(UInt32 finishMode);
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+ STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
+ STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size);
+ STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size);
+
+ #ifndef NO_READ_FROM_CODER
+
+private:
+ CMyComPtr<ISequentialInStream> _inStream;
+public:
+
+ STDMETHOD(SetInStream)(ISequentialInStream *inStream);
+ STDMETHOD(ReleaseInStream)();
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+
+ HRESULT CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress);
+ HRESULT ReadFromInputStream(void *data, UInt32 size, UInt32 *processedSize);
+
+ #endif
+
+ UInt64 GetInputProcessedSize() const { return _inProcessed; }
+
+ CDecoder();
+ virtual ~CDecoder();
+
+ UInt64 GetOutputProcessedSize() const { return _outProcessed; }
+
+ bool NeedsMoreInput() const { return _lzmaStatus == LZMA_STATUS_NEEDS_MORE_INPUT; }
+
+ bool CheckFinishStatus(bool withEndMark) const
+ {
+ return _lzmaStatus == (withEndMark ?
+ LZMA_STATUS_FINISHED_WITH_MARK :
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK);
+ }
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/LzmaEncoder.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/LzmaEncoder.cpp
new file mode 100644
index 000000000..3151c3d21
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/LzmaEncoder.cpp
@@ -0,0 +1,182 @@
+// LzmaEncoder.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/Alloc.h"
+
+#include "../Common/CWrappers.h"
+#include "../Common/StreamUtils.h"
+
+#include "LzmaEncoder.h"
+
+namespace NCompress {
+namespace NLzma {
+
+CEncoder::CEncoder()
+{
+ _encoder = NULL;
+ _encoder = LzmaEnc_Create(&g_AlignedAlloc);
+ if (!_encoder)
+ throw 1;
+}
+
+CEncoder::~CEncoder()
+{
+ if (_encoder)
+ LzmaEnc_Destroy(_encoder, &g_AlignedAlloc, &g_BigAlloc);
+}
+
+static inline wchar_t GetUpperChar(wchar_t c)
+{
+ if (c >= 'a' && c <= 'z')
+ c -= 0x20;
+ return c;
+}
+
+static int ParseMatchFinder(const wchar_t *s, int *btMode, int *numHashBytes)
+{
+ wchar_t c = GetUpperChar(*s++);
+ if (c == L'H')
+ {
+ if (GetUpperChar(*s++) != L'C')
+ return 0;
+ int numHashBytesLoc = (int)(*s++ - L'0');
+ if (numHashBytesLoc < 4 || numHashBytesLoc > 4)
+ return 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;
+ if (*s != 0)
+ return 0;
+ *btMode = 1;
+ *numHashBytes = numHashBytesLoc;
+ return 1;
+}
+
+#define SET_PROP_32(_id_, _dest_) case NCoderPropID::_id_: ep._dest_ = v; break;
+
+HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep)
+{
+ if (propID == NCoderPropID::kMatchFinder)
+ {
+ if (prop.vt != VT_BSTR)
+ return E_INVALIDARG;
+ return ParseMatchFinder(prop.bstrVal, &ep.btMode, &ep.numHashBytes) ? S_OK : E_INVALIDARG;
+ }
+
+ if (propID > NCoderPropID::kReduceSize)
+ return S_OK;
+
+ if (propID == NCoderPropID::kReduceSize)
+ {
+ if (prop.vt == VT_UI8)
+ ep.reduceSize = prop.uhVal.QuadPart;
+ else
+ return E_INVALIDARG;
+ return S_OK;
+ }
+
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 v = prop.ulVal;
+ switch (propID)
+ {
+ case NCoderPropID::kDefaultProp: if (v > 31) return E_INVALIDARG; ep.dictSize = (UInt32)1 << (unsigned)v; break;
+ SET_PROP_32(kLevel, level)
+ SET_PROP_32(kNumFastBytes, fb)
+ SET_PROP_32(kMatchFinderCycles, mc)
+ SET_PROP_32(kAlgorithm, algo)
+ SET_PROP_32(kDictionarySize, dictSize)
+ SET_PROP_32(kPosStateBits, pb)
+ SET_PROP_32(kLitPosBits, lp)
+ SET_PROP_32(kLitContextBits, lc)
+ SET_PROP_32(kNumThreads, numThreads)
+ default: return E_INVALIDARG;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
+ const PROPVARIANT *coderProps, UInt32 numProps)
+{
+ CLzmaEncProps props;
+ LzmaEncProps_Init(&props);
+
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ const PROPVARIANT &prop = coderProps[i];
+ PROPID propID = propIDs[i];
+ switch (propID)
+ {
+ case NCoderPropID::kEndMarker:
+ if (prop.vt != VT_BOOL) return E_INVALIDARG; props.writeEndMark = (prop.boolVal != VARIANT_FALSE); break;
+ default:
+ RINOK(SetLzmaProp(propID, prop, props));
+ }
+ }
+ return SResToHRESULT(LzmaEnc_SetProps(_encoder, &props));
+}
+
+
+STDMETHODIMP CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs,
+ const PROPVARIANT *coderProps, UInt32 numProps)
+{
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ const PROPVARIANT &prop = coderProps[i];
+ PROPID propID = propIDs[i];
+ if (propID == NCoderPropID::kExpectedDataSize)
+ if (prop.vt == VT_UI8)
+ LzmaEnc_SetDataSize(_encoder, prop.uhVal.QuadPart);
+ }
+ return S_OK;
+}
+
+
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ Byte props[LZMA_PROPS_SIZE];
+ size_t size = LZMA_PROPS_SIZE;
+ RINOK(LzmaEnc_WriteProperties(_encoder, props, &size));
+ return WriteStream(outStream, props, size);
+}
+
+
+#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
+ if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
+
+STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
+{
+ CSeqInStreamWrap inWrap;
+ CSeqOutStreamWrap outWrap;
+ CCompressProgressWrap progressWrap;
+
+ inWrap.Init(inStream);
+ outWrap.Init(outStream);
+ progressWrap.Init(progress);
+
+ SRes res = LzmaEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt,
+ progress ? &progressWrap.vt : NULL, &g_AlignedAlloc, &g_BigAlloc);
+
+ _inputProcessed = inWrap.Processed;
+
+ RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ)
+ RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
+ RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
+
+ return SResToHRESULT(res);
+}
+
+}}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/LzmaEncoder.h b/other-licenses/7zstub/src/CPP/7zip/Compress/LzmaEncoder.h
new file mode 100644
index 000000000..7b31c66d8
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/LzmaEncoder.h
@@ -0,0 +1,46 @@
+// LzmaEncoder.h
+
+#ifndef __LZMA_ENCODER_H
+#define __LZMA_ENCODER_H
+
+#include "../../../C/LzmaEnc.h"
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+
+namespace NCompress {
+namespace NLzma {
+
+class CEncoder:
+ public ICompressCoder,
+ public ICompressSetCoderProperties,
+ public ICompressWriteCoderProperties,
+ public ICompressSetCoderPropertiesOpt,
+ public CMyUnknownImp
+{
+ CLzmaEncHandle _encoder;
+ UInt64 _inputProcessed;
+public:
+ MY_UNKNOWN_IMP4(
+ ICompressCoder,
+ ICompressSetCoderProperties,
+ ICompressWriteCoderProperties,
+ ICompressSetCoderPropertiesOpt)
+
+ STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+ STDMETHOD(SetCoderPropertiesOpt)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+
+ CEncoder();
+ virtual ~CEncoder();
+
+ UInt64 GetInputProcessedSize() const { return _inputProcessed; }
+ bool IsWriteEndMark() const { return LzmaEnc_IsWriteEndMark(_encoder) != 0; }
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/LzmaRegister.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/LzmaRegister.cpp
new file mode 100644
index 000000000..439759508
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/LzmaRegister.cpp
@@ -0,0 +1,22 @@
+// LzmaRegister.cpp
+
+#include "StdAfx.h"
+
+#include "../Common/RegisterCodec.h"
+
+#include "LzmaDecoder.h"
+
+#ifndef EXTRACT_ONLY
+#include "LzmaEncoder.h"
+#endif
+
+namespace NCompress {
+namespace NLzma {
+
+REGISTER_CODEC_E(LZMA,
+ CDecoder(),
+ CEncoder(),
+ 0x30101,
+ "LZMA")
+
+}}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/PpmdDecoder.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/PpmdDecoder.cpp
new file mode 100644
index 000000000..4820c0a7c
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/PpmdDecoder.cpp
@@ -0,0 +1,170 @@
+// PpmdDecoder.cpp
+// 2009-03-11 : Igor Pavlov : Public domain
+
+#include "StdAfx.h"
+
+#include "../../../C/Alloc.h"
+#include "../../../C/CpuArch.h"
+
+#include "../Common/StreamUtils.h"
+
+#include "PpmdDecoder.h"
+
+namespace NCompress {
+namespace NPpmd {
+
+static const UInt32 kBufSize = (1 << 20);
+
+enum
+{
+ kStatus_NeedInit,
+ kStatus_Normal,
+ kStatus_Finished,
+ kStatus_Error
+};
+
+CDecoder::~CDecoder()
+{
+ ::MidFree(_outBuf);
+ Ppmd7_Free(&_ppmd, &g_BigAlloc);
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)
+{
+ if (size < 5)
+ return E_INVALIDARG;
+ _order = props[0];
+ UInt32 memSize = GetUi32(props + 1);
+ if (_order < PPMD7_MIN_ORDER ||
+ _order > PPMD7_MAX_ORDER ||
+ memSize < PPMD7_MIN_MEM_SIZE ||
+ memSize > PPMD7_MAX_MEM_SIZE)
+ return E_NOTIMPL;
+ if (!_inStream.Alloc(1 << 20))
+ return E_OUTOFMEMORY;
+ if (!Ppmd7_Alloc(&_ppmd, memSize, &g_BigAlloc))
+ return E_OUTOFMEMORY;
+ return S_OK;
+}
+
+HRESULT CDecoder::CodeSpec(Byte *memStream, UInt32 size)
+{
+ switch (_status)
+ {
+ case kStatus_Finished: return S_OK;
+ case kStatus_Error: return S_FALSE;
+ case kStatus_NeedInit:
+ _inStream.Init();
+ if (!Ppmd7z_RangeDec_Init(&_rangeDec))
+ {
+ _status = kStatus_Error;
+ return S_FALSE;
+ }
+ _status = kStatus_Normal;
+ Ppmd7_Init(&_ppmd, _order);
+ break;
+ }
+ if (_outSizeDefined)
+ {
+ const UInt64 rem = _outSize - _processedSize;
+ if (size > rem)
+ size = (UInt32)rem;
+ }
+
+ UInt32 i;
+ int sym = 0;
+ for (i = 0; i != size; i++)
+ {
+ sym = Ppmd7_DecodeSymbol(&_ppmd, &_rangeDec.vt);
+ if (_inStream.Extra || sym < 0)
+ break;
+ memStream[i] = (Byte)sym;
+ }
+
+ _processedSize += i;
+ if (_inStream.Extra)
+ {
+ _status = kStatus_Error;
+ return _inStream.Res;
+ }
+ if (sym < 0)
+ _status = (sym < -1) ? kStatus_Error : kStatus_Finished;
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
+{
+ if (!_outBuf)
+ {
+ _outBuf = (Byte *)::MidAlloc(kBufSize);
+ if (!_outBuf)
+ return E_OUTOFMEMORY;
+ }
+
+ _inStream.Stream = inStream;
+ SetOutStreamSize(outSize);
+
+ do
+ {
+ const UInt64 startPos = _processedSize;
+ HRESULT res = CodeSpec(_outBuf, kBufSize);
+ size_t processed = (size_t)(_processedSize - startPos);
+ RINOK(WriteStream(outStream, _outBuf, processed));
+ RINOK(res);
+ if (_status == kStatus_Finished)
+ break;
+ if (progress)
+ {
+ UInt64 inSize = _inStream.GetProcessed();
+ RINOK(progress->SetRatioInfo(&inSize, &_processedSize));
+ }
+ }
+ while (!_outSizeDefined || _processedSize < _outSize);
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
+{
+ _outSizeDefined = (outSize != NULL);
+ if (_outSizeDefined)
+ _outSize = *outSize;
+ _processedSize = 0;
+ _status = kStatus_NeedInit;
+ return S_OK;
+}
+
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ *value = _inStream.GetProcessed();
+ return S_OK;
+}
+
+#ifndef NO_READ_FROM_CODER
+
+STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream)
+{
+ InSeqStream = inStream;
+ _inStream.Stream = inStream;
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::ReleaseInStream()
+{
+ InSeqStream.Release();
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ const UInt64 startPos = _processedSize;
+ HRESULT res = CodeSpec((Byte *)data, size);
+ if (processedSize)
+ *processedSize = (UInt32)(_processedSize - startPos);
+ return res;
+}
+
+#endif
+
+}}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/PpmdDecoder.h b/other-licenses/7zstub/src/CPP/7zip/Compress/PpmdDecoder.h
new file mode 100644
index 000000000..3c2f49349
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/PpmdDecoder.h
@@ -0,0 +1,86 @@
+// PpmdDecoder.h
+// 2009-03-11 : Igor Pavlov : Public domain
+
+#ifndef __COMPRESS_PPMD_DECODER_H
+#define __COMPRESS_PPMD_DECODER_H
+
+#include "../../../C/Ppmd7.h"
+
+#include "../../Common/MyCom.h"
+
+#include "../Common/CWrappers.h"
+
+#include "../ICoder.h"
+
+namespace NCompress {
+namespace NPpmd {
+
+class CDecoder :
+ public ICompressCoder,
+ public ICompressSetDecoderProperties2,
+ public ICompressGetInStreamProcessedSize,
+ #ifndef NO_READ_FROM_CODER
+ public ICompressSetInStream,
+ public ICompressSetOutStreamSize,
+ public ISequentialInStream,
+ #endif
+ public CMyUnknownImp
+{
+ Byte *_outBuf;
+ CPpmd7z_RangeDec _rangeDec;
+ CByteInBufWrap _inStream;
+ CPpmd7 _ppmd;
+
+ Byte _order;
+ bool _outSizeDefined;
+ int _status;
+ UInt64 _outSize;
+ UInt64 _processedSize;
+
+ HRESULT CodeSpec(Byte *memStream, UInt32 size);
+
+public:
+
+ #ifndef NO_READ_FROM_CODER
+ CMyComPtr<ISequentialInStream> InSeqStream;
+ #endif
+
+ MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
+ MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2)
+ // MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode)
+ MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize)
+ #ifndef NO_READ_FROM_CODER
+ 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(SetDecoderProperties2)(const Byte *data, UInt32 size);
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+
+ STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
+
+ #ifndef NO_READ_FROM_CODER
+ STDMETHOD(SetInStream)(ISequentialInStream *inStream);
+ STDMETHOD(ReleaseInStream)();
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ #endif
+
+ CDecoder(): _outBuf(NULL), _outSizeDefined(false)
+ {
+ Ppmd7z_RangeDec_CreateVTable(&_rangeDec);
+ _rangeDec.Stream = &_inStream.vt;
+ Ppmd7_Construct(&_ppmd);
+ }
+
+ ~CDecoder();
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/PpmdEncoder.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/PpmdEncoder.cpp
new file mode 100644
index 000000000..0aef701d0
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/PpmdEncoder.cpp
@@ -0,0 +1,152 @@
+// PpmdEncoder.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/Alloc.h"
+#include "../../../C/CpuArch.h"
+
+#include "../Common/StreamUtils.h"
+
+#include "PpmdEncoder.h"
+
+namespace NCompress {
+namespace NPpmd {
+
+static const UInt32 kBufSize = (1 << 20);
+
+static const Byte kOrders[10] = { 3, 4, 4, 5, 5, 6, 8, 16, 24, 32 };
+
+void CEncProps::Normalize(int level)
+{
+ if (level < 0) level = 5;
+ if (level > 9) level = 9;
+ if (MemSize == (UInt32)(Int32)-1)
+ MemSize = level >= 9 ? ((UInt32)192 << 20) : ((UInt32)1 << (level + 19));
+ const unsigned kMult = 16;
+ if (MemSize / kMult > ReduceSize)
+ {
+ for (unsigned i = 16; i <= 31; i++)
+ {
+ UInt32 m = (UInt32)1 << i;
+ if (ReduceSize <= m / kMult)
+ {
+ if (MemSize > m)
+ MemSize = m;
+ break;
+ }
+ }
+ }
+ if (Order == -1) Order = kOrders[(unsigned)level];
+}
+
+CEncoder::CEncoder():
+ _inBuf(NULL)
+{
+ _props.Normalize(-1);
+ _rangeEnc.Stream = &_outStream.vt;
+ Ppmd7_Construct(&_ppmd);
+}
+
+CEncoder::~CEncoder()
+{
+ ::MidFree(_inBuf);
+ Ppmd7_Free(&_ppmd, &g_BigAlloc);
+}
+
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)
+{
+ int level = -1;
+ CEncProps props;
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ const PROPVARIANT &prop = coderProps[i];
+ PROPID propID = propIDs[i];
+ if (propID > NCoderPropID::kReduceSize)
+ continue;
+ if (propID == NCoderPropID::kReduceSize)
+ {
+ if (prop.vt == VT_UI8 && prop.uhVal.QuadPart < (UInt32)(Int32)-1)
+ props.ReduceSize = (UInt32)prop.uhVal.QuadPart;
+ continue;
+ }
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 v = (UInt32)prop.ulVal;
+ switch (propID)
+ {
+ case NCoderPropID::kUsedMemorySize:
+ if (v < (1 << 16) || v > PPMD7_MAX_MEM_SIZE || (v & 3) != 0)
+ return E_INVALIDARG;
+ props.MemSize = v;
+ break;
+ case NCoderPropID::kOrder:
+ if (v < 2 || v > 32)
+ return E_INVALIDARG;
+ props.Order = (Byte)v;
+ break;
+ case NCoderPropID::kNumThreads: break;
+ case NCoderPropID::kLevel: level = (int)v; break;
+ default: return E_INVALIDARG;
+ }
+ }
+ props.Normalize(level);
+ _props = props;
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ const UInt32 kPropSize = 5;
+ Byte props[kPropSize];
+ props[0] = (Byte)_props.Order;
+ SetUi32(props + 1, _props.MemSize);
+ return WriteStream(outStream, props, kPropSize);
+}
+
+HRESULT CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
+{
+ if (!_inBuf)
+ {
+ _inBuf = (Byte *)::MidAlloc(kBufSize);
+ if (!_inBuf)
+ return E_OUTOFMEMORY;
+ }
+ if (!_outStream.Alloc(1 << 20))
+ return E_OUTOFMEMORY;
+ if (!Ppmd7_Alloc(&_ppmd, _props.MemSize, &g_BigAlloc))
+ return E_OUTOFMEMORY;
+
+ _outStream.Stream = outStream;
+ _outStream.Init();
+
+ Ppmd7z_RangeEnc_Init(&_rangeEnc);
+ Ppmd7_Init(&_ppmd, _props.Order);
+
+ UInt64 processed = 0;
+ for (;;)
+ {
+ UInt32 size;
+ RINOK(inStream->Read(_inBuf, kBufSize, &size));
+ if (size == 0)
+ {
+ // We don't write EndMark in PPMD-7z.
+ // Ppmd7_EncodeSymbol(&_ppmd, &_rangeEnc, -1);
+ Ppmd7z_RangeEnc_FlushData(&_rangeEnc);
+ return _outStream.Flush();
+ }
+ for (UInt32 i = 0; i < size; i++)
+ {
+ Ppmd7_EncodeSymbol(&_ppmd, &_rangeEnc, _inBuf[i]);
+ RINOK(_outStream.Res);
+ }
+ processed += size;
+ if (progress)
+ {
+ UInt64 outSize = _outStream.GetProcessed();
+ RINOK(progress->SetRatioInfo(&processed, &outSize));
+ }
+ }
+}
+
+}}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/PpmdEncoder.h b/other-licenses/7zstub/src/CPP/7zip/Compress/PpmdEncoder.h
new file mode 100644
index 000000000..cdb0352b7
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/PpmdEncoder.h
@@ -0,0 +1,58 @@
+// PpmdEncoder.h
+
+#ifndef __COMPRESS_PPMD_ENCODER_H
+#define __COMPRESS_PPMD_ENCODER_H
+
+#include "../../../C/Ppmd7.h"
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+
+#include "../Common/CWrappers.h"
+
+namespace NCompress {
+namespace NPpmd {
+
+struct CEncProps
+{
+ UInt32 MemSize;
+ UInt32 ReduceSize;
+ int Order;
+
+ CEncProps()
+ {
+ MemSize = (UInt32)(Int32)-1;
+ ReduceSize = (UInt32)(Int32)-1;
+ Order = -1;
+ }
+ void Normalize(int level);
+};
+
+class CEncoder :
+ public ICompressCoder,
+ public ICompressSetCoderProperties,
+ public ICompressWriteCoderProperties,
+ public CMyUnknownImp
+{
+ Byte *_inBuf;
+ CByteOutBufWrap _outStream;
+ CPpmd7z_RangeEnc _rangeEnc;
+ CPpmd7 _ppmd;
+ CEncProps _props;
+public:
+ MY_UNKNOWN_IMP3(
+ ICompressCoder,
+ ICompressSetCoderProperties,
+ ICompressWriteCoderProperties)
+ STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+ CEncoder();
+ ~CEncoder();
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/PpmdRegister.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/PpmdRegister.cpp
new file mode 100644
index 000000000..c7486966c
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/PpmdRegister.cpp
@@ -0,0 +1,22 @@
+// PpmdRegister.cpp
+
+#include "StdAfx.h"
+
+#include "../Common/RegisterCodec.h"
+
+#include "PpmdDecoder.h"
+
+#ifndef EXTRACT_ONLY
+#include "PpmdEncoder.h"
+#endif
+
+namespace NCompress {
+namespace NPpmd {
+
+REGISTER_CODEC_E(PPMD,
+ CDecoder(),
+ CEncoder(),
+ 0x30401,
+ "PPMD")
+
+}}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/StdAfx.h b/other-licenses/7zstub/src/CPP/7zip/Compress/StdAfx.h
new file mode 100644
index 000000000..42a088f12
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../Common/Common.h"
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/XzDecoder.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/XzDecoder.cpp
new file mode 100644
index 000000000..4fcd09fe8
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/XzDecoder.cpp
@@ -0,0 +1,150 @@
+// XzDecoder.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/Alloc.h"
+
+#include "../Common/CWrappers.h"
+
+#include "XzDecoder.h"
+
+namespace NCompress {
+namespace NXz {
+
+#define RET_IF_WRAP_ERROR_CONFIRMED(wrapRes, sRes, sResErrorCode) \
+ if (wrapRes != S_OK && sRes == sResErrorCode) return wrapRes;
+
+#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
+ if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
+
+static HRESULT SResToHRESULT_Code(SRes res) throw()
+{
+ if (res < 0)
+ return res;
+ switch (res)
+ {
+ case SZ_OK: return S_OK;
+ case SZ_ERROR_MEM: return E_OUTOFMEMORY;
+ case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL;
+ }
+ return S_FALSE;
+}
+
+
+HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream,
+ const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *progress)
+{
+ MainDecodeSRes = S_OK;
+ MainDecodeSRes_wasUsed = false;
+ XzStatInfo_Clear(&Stat);
+
+ if (!xz)
+ {
+ xz = XzDecMt_Create(&g_Alloc, &g_MidAlloc);
+ if (!xz)
+ return E_OUTOFMEMORY;
+ }
+
+ CXzDecMtProps props;
+ XzDecMtProps_Init(&props);
+
+ int isMT = False;
+
+ #ifndef _7ZIP_ST
+ {
+ props.numThreads = 1;
+ UInt32 numThreads = _numThreads;
+
+ if (_tryMt && numThreads > 1)
+ {
+ size_t memUsage = (size_t)_memUsage;
+ if (memUsage != _memUsage)
+ memUsage = (size_t)0 - 1;
+ props.memUseMax = memUsage;
+ isMT = (numThreads > 1);
+ }
+
+ props.numThreads = numThreads;
+ }
+ #endif
+
+ CSeqInStreamWrap inWrap;
+ CSeqOutStreamWrap outWrap;
+ CCompressProgressWrap progressWrap;
+
+ inWrap.Init(seqInStream);
+ outWrap.Init(outStream);
+ progressWrap.Init(progress);
+
+ SRes res = XzDecMt_Decode(xz,
+ &props,
+ outSizeLimit, finishStream,
+ &outWrap.vt,
+ &inWrap.vt,
+ &Stat,
+ &isMT,
+ progress ? &progressWrap.vt : NULL);
+
+ MainDecodeSRes = res;
+
+ #ifndef _7ZIP_ST
+ // _tryMt = isMT;
+ #endif
+
+ RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
+ RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
+ RET_IF_WRAP_ERROR_CONFIRMED(inWrap.Res, res, SZ_ERROR_READ)
+
+ // return E_OUTOFMEMORY;
+
+ MainDecodeSRes_wasUsed = true;
+
+ if (res == SZ_OK && finishStream)
+ {
+ /*
+ if (inSize && *inSize != Stat.PhySize)
+ res = SZ_ERROR_DATA;
+ */
+ if (outSizeLimit && *outSizeLimit != outWrap.Processed)
+ res = SZ_ERROR_DATA;
+ }
+
+ return SResToHRESULT_Code(res);
+}
+
+
+HRESULT CComDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
+{
+ return Decode(inStream, outStream, outSize, _finishStream, progress);
+}
+
+STDMETHODIMP CComDecoder::SetFinishMode(UInt32 finishMode)
+{
+ _finishStream = (finishMode != 0);
+ return S_OK;
+}
+
+STDMETHODIMP CComDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ *value = Stat.InSize;
+ return S_OK;
+}
+
+#ifndef _7ZIP_ST
+
+STDMETHODIMP CComDecoder::SetNumberOfThreads(UInt32 numThreads)
+{
+ _numThreads = numThreads;
+ return S_OK;
+}
+
+STDMETHODIMP CComDecoder::SetMemLimit(UInt64 memUsage)
+{
+ _memUsage = memUsage;
+ return S_OK;
+}
+
+#endif
+
+}}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/XzDecoder.h b/other-licenses/7zstub/src/CPP/7zip/Compress/XzDecoder.h
new file mode 100644
index 000000000..76694eec0
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/XzDecoder.h
@@ -0,0 +1,92 @@
+// XzDecoder.h
+
+#ifndef __XZ_DECODER_H
+#define __XZ_DECODER_H
+
+#include "../../../C/Xz.h"
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+
+namespace NCompress {
+namespace NXz {
+
+struct CDecoder
+{
+ CXzDecMtHandle xz;
+ int _tryMt;
+ UInt32 _numThreads;
+ UInt64 _memUsage;
+
+ SRes MainDecodeSRes; // it's not HRESULT
+ bool MainDecodeSRes_wasUsed;
+ CXzStatInfo Stat;
+
+ CDecoder():
+ xz(NULL),
+ _tryMt(True),
+ _numThreads(1),
+ _memUsage((UInt64)(sizeof(size_t)) << 28),
+ MainDecodeSRes(SZ_OK),
+ MainDecodeSRes_wasUsed(false)
+ {}
+
+ ~CDecoder()
+ {
+ if (xz)
+ XzDecMt_Destroy(xz);
+ }
+
+ /* Decode() can return ERROR code only if there is progress or stream error.
+ Decode() returns S_OK in case of xz decoding error, but DecodeRes and CStatInfo contain error information */
+ HRESULT Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream,
+ const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *compressProgress);
+};
+
+
+class CComDecoder:
+ public ICompressCoder,
+ public ICompressSetFinishMode,
+ public ICompressGetInStreamProcessedSize,
+
+ #ifndef _7ZIP_ST
+ public ICompressSetCoderMt,
+ public ICompressSetMemLimit,
+ #endif
+
+ public CMyUnknownImp,
+ public CDecoder
+{
+ bool _finishStream;
+
+public:
+ MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
+
+ MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode)
+ MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize)
+
+ #ifndef _7ZIP_ST
+ MY_QUERYINTERFACE_ENTRY(ICompressSetCoderMt)
+ MY_QUERYINTERFACE_ENTRY(ICompressSetMemLimit)
+ #endif
+
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+
+ STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
+ STDMETHOD(SetFinishMode)(UInt32 finishMode);
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+
+ #ifndef _7ZIP_ST
+ STDMETHOD(SetNumberOfThreads)(UInt32 numThreads);
+ STDMETHOD(SetMemLimit)(UInt64 memUsage);
+ #endif
+
+ CComDecoder(): _finishStream(false) {}
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/XzEncoder.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/XzEncoder.cpp
new file mode 100644
index 000000000..458a928c9
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/XzEncoder.cpp
@@ -0,0 +1,245 @@
+// XzEncoder.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/Alloc.h"
+
+#include "../../Common/MyString.h"
+#include "../../Common/StringToInt.h"
+
+#include "../Common/CWrappers.h"
+#include "../Common/StreamUtils.h"
+
+#include "XzEncoder.h"
+
+namespace NCompress {
+
+namespace NLzma2 {
+
+HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props);
+
+}
+
+namespace NXz {
+
+void CEncoder::InitCoderProps()
+{
+ XzProps_Init(&xzProps);
+}
+
+CEncoder::CEncoder()
+{
+ XzProps_Init(&xzProps);
+ _encoder = NULL;
+ _encoder = XzEnc_Create(&g_Alloc, &g_BigAlloc);
+ if (!_encoder)
+ throw 1;
+}
+
+CEncoder::~CEncoder()
+{
+ if (_encoder)
+ XzEnc_Destroy(_encoder);
+}
+
+
+struct CMethodNamePair
+{
+ UInt32 Id;
+ const char *Name;
+};
+
+static const CMethodNamePair g_NamePairs[] =
+{
+ { XZ_ID_Delta, "Delta" },
+ { XZ_ID_X86, "BCJ" },
+ { XZ_ID_PPC, "PPC" },
+ { XZ_ID_IA64, "IA64" },
+ { XZ_ID_ARM, "ARM" },
+ { XZ_ID_ARMT, "ARMT" },
+ { XZ_ID_SPARC, "SPARC" }
+ // { XZ_ID_LZMA2, "LZMA2" }
+};
+
+static int FilterIdFromName(const wchar_t *name)
+{
+ for (unsigned i = 0; i < ARRAY_SIZE(g_NamePairs); i++)
+ {
+ const CMethodNamePair &pair = g_NamePairs[i];
+ if (StringsAreEqualNoCase_Ascii(name, pair.Name))
+ return (int)pair.Id;
+ }
+ return -1;
+}
+
+
+HRESULT CEncoder::SetCheckSize(UInt32 checkSizeInBytes)
+{
+ unsigned id;
+ switch (checkSizeInBytes)
+ {
+ case 0: id = XZ_CHECK_NO; break;
+ case 4: id = XZ_CHECK_CRC32; break;
+ case 8: id = XZ_CHECK_CRC64; break;
+ case 32: id = XZ_CHECK_SHA256; break;
+ default: return E_INVALIDARG;
+ }
+ xzProps.checkId = id;
+ return S_OK;
+}
+
+
+HRESULT CEncoder::SetCoderProp(PROPID propID, const PROPVARIANT &prop)
+{
+ if (propID == NCoderPropID::kNumThreads)
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ xzProps.numTotalThreads = (int)(prop.ulVal);
+ return S_OK;
+ }
+
+ if (propID == NCoderPropID::kCheckSize)
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ return SetCheckSize(prop.ulVal);
+ }
+
+ if (propID == NCoderPropID::kBlockSize2)
+ {
+ if (prop.vt == VT_UI4)
+ xzProps.blockSize = prop.ulVal;
+ else if (prop.vt == VT_UI8)
+ xzProps.blockSize = prop.uhVal.QuadPart;
+ else
+ return E_INVALIDARG;
+ return S_OK;
+ }
+
+ if (propID == NCoderPropID::kReduceSize)
+ {
+ if (prop.vt == VT_UI8)
+ xzProps.reduceSize = prop.uhVal.QuadPart;
+ else
+ return E_INVALIDARG;
+ return S_OK;
+ }
+
+ if (propID == NCoderPropID::kFilter)
+ {
+ if (prop.vt == VT_UI4)
+ {
+ UInt32 id32 = prop.ulVal;
+ if (id32 == XZ_ID_Delta)
+ return E_INVALIDARG;
+ xzProps.filterProps.id = prop.ulVal;
+ }
+ else
+ {
+ if (prop.vt != VT_BSTR)
+ return E_INVALIDARG;
+
+ const wchar_t *name = prop.bstrVal;
+ const wchar_t *end;
+
+ UInt32 id32 = ConvertStringToUInt32(name, &end);
+
+ if (end != name)
+ name = end;
+ else
+ {
+ if (IsString1PrefixedByString2_NoCase_Ascii(name, "Delta"))
+ {
+ name += 5; // strlen("Delta");
+ id32 = XZ_ID_Delta;
+ }
+ else
+ {
+ int filterId = FilterIdFromName(prop.bstrVal);
+ if (filterId < 0 /* || filterId == XZ_ID_LZMA2 */)
+ return E_INVALIDARG;
+ id32 = filterId;
+ }
+ }
+
+ if (id32 == XZ_ID_Delta)
+ {
+ wchar_t c = *name;
+ if (c != '-' && c != ':')
+ return E_INVALIDARG;
+ name++;
+ UInt32 delta = ConvertStringToUInt32(name, &end);
+ if (end == name || *end != 0 || delta == 0 || delta > 256)
+ return E_INVALIDARG;
+ xzProps.filterProps.delta = delta;
+ }
+
+ xzProps.filterProps.id = id32;
+ }
+
+ return S_OK;
+ }
+
+ return NLzma2::SetLzma2Prop(propID, prop, xzProps.lzma2Props);
+}
+
+
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
+ const PROPVARIANT *coderProps, UInt32 numProps)
+{
+ XzProps_Init(&xzProps);
+
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ RINOK(SetCoderProp(propIDs[i], coderProps[i]));
+ }
+
+ return S_OK;
+ // return SResToHRESULT(XzEnc_SetProps(_encoder, &xzProps));
+}
+
+
+STDMETHODIMP CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs,
+ const PROPVARIANT *coderProps, UInt32 numProps)
+{
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ const PROPVARIANT &prop = coderProps[i];
+ PROPID propID = propIDs[i];
+ if (propID == NCoderPropID::kExpectedDataSize)
+ if (prop.vt == VT_UI8)
+ XzEnc_SetDataSize(_encoder, prop.uhVal.QuadPart);
+ }
+ return S_OK;
+}
+
+
+#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
+ if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
+
+STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
+{
+ CSeqInStreamWrap inWrap;
+ CSeqOutStreamWrap outWrap;
+ CCompressProgressWrap progressWrap;
+
+ inWrap.Init(inStream);
+ outWrap.Init(outStream);
+ progressWrap.Init(progress);
+
+ SRes res = XzEnc_SetProps(_encoder, &xzProps);
+ if (res == SZ_OK)
+ res = XzEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt, progress ? &progressWrap.vt : NULL);
+
+ // SRes res = Xz_Encode(&outWrap.vt, &inWrap.vt, &xzProps, progress ? &progressWrap.vt : NULL);
+
+ RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ)
+ RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
+ RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
+
+ return SResToHRESULT(res);
+}
+
+}}
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/XzEncoder.h b/other-licenses/7zstub/src/CPP/7zip/Compress/XzEncoder.h
new file mode 100644
index 000000000..79d81f793
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/7zip/Compress/XzEncoder.h
@@ -0,0 +1,46 @@
+// XzEncoder.h
+
+#ifndef __XZ_ENCODER_H
+#define __XZ_ENCODER_H
+
+#include "../../../C/XzEnc.h"
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+
+namespace NCompress {
+namespace NXz {
+
+
+class CEncoder:
+ public ICompressCoder,
+ public ICompressSetCoderProperties,
+ public ICompressSetCoderPropertiesOpt,
+ public CMyUnknownImp
+{
+ CXzEncHandle _encoder;
+public:
+ CXzProps xzProps;
+
+ MY_UNKNOWN_IMP3(
+ ICompressCoder,
+ ICompressSetCoderProperties,
+ ICompressSetCoderPropertiesOpt)
+
+ void InitCoderProps();
+ HRESULT SetCheckSize(UInt32 checkSizeInBytes);
+ HRESULT SetCoderProp(PROPID propID, const PROPVARIANT &prop);
+
+ STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+ STDMETHOD(SetCoderPropertiesOpt)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+
+ CEncoder();
+ virtual ~CEncoder();
+};
+
+}}
+
+#endif