merge multi threading to master branch

- updated zstd to latest devel release
- lz4, lz5 and zstd is included now
- all three support threading
This commit is contained in:
Tino Reichardt
2016-10-16 23:38:46 +02:00
parent f3f39b74b0
commit 58069903d0
108 changed files with 21091 additions and 609 deletions

View File

@@ -27,7 +27,10 @@ OBJS = \
$(COMPRESS_OBJS) \
$(CRYPTO_OBJS) \
$(C_OBJS) \
$(LZ4_OBJS) \
$(LZ5_OBJS) \
$(ZSTD_OBJS) \
$(ZSTDMT_OBJS) \
$(ASM_OBJS) \
$O\resource.res \
@@ -173,11 +176,26 @@ $(C_OBJS): ../../../../C/$(*B).c
$(COMPL_O2)
!ENDIF
!IFDEF LZ4_OBJS
$(LZ4_OBJS): ../../../../C/lz4/$(*B).c
$(COMPL_O2)
!ENDIF
!IFDEF LZ5_OBJS
$(LZ5_OBJS): ../../../../C/lz5/$(*B).c
$(COMPL_O2)
!ENDIF
!IFDEF ZSTD_OBJS
$(ZSTD_OBJS): ../../../../C/zstd/$(*B).c
$(COMPL_O2)
!ENDIF
!IFDEF ZSTDMT_OBJS
$(ZSTDMT_OBJS): ../../../../C/zstdmt/$(*B).c
$(COMPL_O2)
!ENDIF
!ELSE
@@ -240,8 +258,17 @@ $(ZSTD_OBJS): ../../../../C/zstd/$(*B).c
$(COMPLB_O2)
{../../../../C}.c{$O}.obj::
$(CCOMPLB)
{../../../../C/lz4}.c{$O}.obj::
$(CCOMPLB)
{../../../../C/lz5}.c{$O}.obj::
$(CCOMPLB)
{../../../../C/zstd}.c{$O}.obj::
$(CCOMPLB)
{../../../../C/zstdmt}.c{$O}.obj::
$(CCOMPLB) \
-I ../../../../C/lz4 \
-I ../../../../C/lz5 \
-I ../../../../C/zstd
!ENDIF

View File

@@ -558,7 +558,7 @@ static int CompareEmptyItems(const unsigned *p1, const unsigned *p2, void *param
}
static const char *g_Exts =
" 7z xz lzma ace arc arj bz tbz bz2 tbz2 cab deb gz tgz ha lha lzh lzo lzx pak rar rpm sit zoo"
" 7z xz lzma ace arc arj bz tbz bz2 tbz2 cab deb gz tgz ha lha lz tlz lz4 tlz4 lz5 tlz5 lzh lzo lzx pak rar rpm sit zoo zst"
" zip jar ear war msi"
" 3gp avi mov mpeg mpg mpe wmv"
" aac ape fla flac la mp3 m4a mp4 ofr ogg pac ra rm rka shn swa tta wv wma wav"

View File

@@ -155,7 +155,7 @@ IArchiveExtractCallback::GetStream()
if (IProgress::SetTotal() was called)
{
IProgress::SetCompleted(completeValue) uses
packSize - for some stream formats (xz, gz, bz2, lzma, z, ppmd).
packSize - for some stream formats (xz, gz, bz2, lz, lzma, z, ppmd).
unpackSize - for another formats.
}
else

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -0,0 +1,366 @@
// ZstdHandler.cpp
#include "StdAfx.h"
#include "../../../C/CpuArch.h"
#include "../../Common/ComTry.h"
#include "../../Common/Defs.h"
#include "../Common/ProgressUtils.h"
#include "../Common/RegisterArc.h"
#include "../Common/StreamUtils.h"
#include "../Compress/Lz4Decoder.h"
#include "../Compress/Lz4Encoder.h"
#include "../Compress/CopyCoder.h"
#include "Common/DummyOutStream.h"
#include "Common/HandlerOut.h"
using namespace NWindows;
namespace NArchive {
namespace NLZ4 {
class CHandler:
public IInArchive,
public IArchiveOpenSeq,
public IOutArchive,
public ISetProperties,
public CMyUnknownImp
{
CMyComPtr<IInStream> _stream;
CMyComPtr<ISequentialInStream> _seqStream;
bool _isArc;
bool _dataAfterEnd;
bool _needMoreInput;
bool _packSize_Defined;
bool _unpackSize_Defined;
UInt64 _packSize;
UInt64 _unpackSize;
UInt64 _numStreams;
UInt64 _numBlocks;
CSingleMethodProps _props;
public:
MY_UNKNOWN_IMP4(
IInArchive,
IArchiveOpenSeq,
IOutArchive,
ISetProperties)
INTERFACE_IInArchive(;)
INTERFACE_IOutArchive(;)
STDMETHOD(OpenSeq)(ISequentialInStream *stream);
STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
CHandler() { }
};
static const Byte kProps[] =
{
kpidSize,
kpidPackSize
};
static const Byte kArcProps[] =
{
kpidNumStreams,
kpidNumBlocks
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /*propID*/, PROPVARIANT * /*value*/)
{
return S_OK;
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems = 1;
return S_OK;
}
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
{
NCOM::CPropVariant prop;
switch (propID)
{
case kpidPackSize: if (_packSize_Defined) prop = _packSize; break;
case kpidSize: if (_unpackSize_Defined) prop = _unpackSize; break;
}
prop.Detach(value);
return S_OK;
}
static const unsigned kSignatureCheckSize = 4;
API_FUNC_static_IsArc IsArc_lz4(const Byte *p, size_t size)
{
if (size < 4)
return k_IsArc_Res_NEED_MORE;
UInt32 magic = GetUi32(p);
// skippable frames
if (magic >= 0x184D2A50 && magic <= 0x184D2A5F) {
if (size < 16)
return k_IsArc_Res_NEED_MORE;
magic = GetUi32(p+12);
}
// lz4 magic
if (magic == 0x184D2204)
return k_IsArc_Res_YES;
return k_IsArc_Res_NO;
}
}
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *)
{
COM_TRY_BEGIN
Close();
{
Byte buf[kSignatureCheckSize];
RINOK(ReadStream_FALSE(stream, buf, kSignatureCheckSize));
if (IsArc_lz4(buf, kSignatureCheckSize) == k_IsArc_Res_NO)
return S_FALSE;
_isArc = true;
_stream = stream;
_seqStream = stream;
RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
}
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
{
Close();
_isArc = true;
_seqStream = stream;
return S_OK;
}
STDMETHODIMP CHandler::Close()
{
_isArc = false;
_dataAfterEnd = false;
_needMoreInput = false;
_packSize_Defined = false;
_unpackSize_Defined = false;
_packSize = 0;
_seqStream.Release();
_stream.Release();
return S_OK;
}
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
if (numItems == 0)
return S_OK;
if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
return E_INVALIDARG;
if (_packSize_Defined)
extractCallback->SetTotal(_packSize);
CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
if (!testMode && !realOutStream)
return S_OK;
extractCallback->PrepareOperation(askMode);
Int32 opRes;
{
NCompress::NLZ4::CDecoder *decoderSpec = new NCompress::NLZ4::CDecoder;
CMyComPtr<ICompressCoder> decoder = decoderSpec;
decoderSpec->SetInStream(_seqStream);
CDummyOutStream *outStreamSpec = new CDummyOutStream;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->SetStream(realOutStream);
outStreamSpec->Init();
realOutStream.Release();
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, true);
UInt64 packSize = 0;
UInt64 unpackedSize = 0;
HRESULT result = S_OK;
for (;;)
{
lps->InSize = packSize;
lps->OutSize = unpackedSize;
RINOK(lps->SetCur());
result = decoderSpec->CodeResume(outStream, &unpackedSize, progress);
UInt64 streamSize = decoderSpec->GetInputProcessedSize();
if (result != S_FALSE && result != S_OK)
return result;
if (unpackedSize == 0)
break;
if (streamSize == packSize)
{
// no new bytes in input stream, So it's good end of archive.
result = S_OK;
break;
}
if (packSize > streamSize)
return E_FAIL;
if (result != S_OK)
break;
}
decoderSpec->ReleaseInStream();
outStream.Release();
if (!_isArc)
opRes = NExtract::NOperationResult::kIsNotArc;
else if (_needMoreInput)
opRes = NExtract::NOperationResult::kUnexpectedEnd;
else if (_dataAfterEnd)
opRes = NExtract::NOperationResult::kDataAfterEnd;
else if (result == S_FALSE)
opRes = NExtract::NOperationResult::kDataError;
else if (result == S_OK)
opRes = NExtract::NOperationResult::kOK;
else
return result;
}
return extractCallback->SetOperationResult(opRes);
COM_TRY_END
}
static HRESULT UpdateArchive(
UInt64 unpackSize,
ISequentialOutStream *outStream,
const CProps &props,
IArchiveUpdateCallback *updateCallback)
{
RINOK(updateCallback->SetTotal(unpackSize));
CMyComPtr<ISequentialInStream> fileInStream;
RINOK(updateCallback->GetStream(0, &fileInStream));
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
localProgressSpec->Init(updateCallback, true);
NCompress::NLZ4::CEncoder *encoderSpec = new NCompress::NLZ4::CEncoder;
CMyComPtr<ICompressCoder> encoder = encoderSpec;
RINOK(props.SetCoderProps(encoderSpec, NULL));
RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress));
return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
}
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
{
*type = NFileTimeType::kUnix;
return S_OK;
}
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *updateCallback)
{
COM_TRY_BEGIN
if (numItems != 1)
return E_INVALIDARG;
Int32 newData, newProps;
UInt32 indexInArchive;
if (!updateCallback)
return E_FAIL;
RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive));
if ((newProps))
{
{
NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop));
if (prop.vt != VT_EMPTY)
if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE)
return E_INVALIDARG;
}
}
if ((newData))
{
UInt64 size;
{
NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(0, kpidSize, &prop));
if (prop.vt != VT_UI8)
return E_INVALIDARG;
size = prop.uhVal.QuadPart;
}
return UpdateArchive(size, outStream, _props, updateCallback);
}
if (indexInArchive != 0)
return E_INVALIDARG;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(updateCallback, true);
CMyComPtr<IArchiveUpdateCallbackFile> opCallback;
updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback);
if (opCallback)
{
RINOK(opCallback->ReportOperation(
NEventIndexType::kInArcIndex, 0,
NUpdateNotifyOp::kReplicate))
}
if (_stream)
RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
return NCompress::CopyStream(_stream, outStream, progress);
COM_TRY_END
}
STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
return _props.SetProperties(names, values, numProps);
}
static const Byte k_Signature[] = "0x184D2204";
REGISTER_ARC_IO(
"lz4", "lz4 tlz4", "* .tar", 0x0f,
k_Signature,
0,
NArcInfoFlags::kKeepName,
IsArc_lz4)
}}

View File

@@ -0,0 +1,366 @@
// ZstdHandler.cpp
#include "StdAfx.h"
#include "../../../C/CpuArch.h"
#include "../../Common/ComTry.h"
#include "../../Common/Defs.h"
#include "../Common/ProgressUtils.h"
#include "../Common/RegisterArc.h"
#include "../Common/StreamUtils.h"
#include "../Compress/Lz5Decoder.h"
#include "../Compress/Lz5Encoder.h"
#include "../Compress/CopyCoder.h"
#include "Common/DummyOutStream.h"
#include "Common/HandlerOut.h"
using namespace NWindows;
namespace NArchive {
namespace NLZ5 {
class CHandler:
public IInArchive,
public IArchiveOpenSeq,
public IOutArchive,
public ISetProperties,
public CMyUnknownImp
{
CMyComPtr<IInStream> _stream;
CMyComPtr<ISequentialInStream> _seqStream;
bool _isArc;
bool _dataAfterEnd;
bool _needMoreInput;
bool _packSize_Defined;
bool _unpackSize_Defined;
UInt64 _packSize;
UInt64 _unpackSize;
UInt64 _numStreams;
UInt64 _numBlocks;
CSingleMethodProps _props;
public:
MY_UNKNOWN_IMP4(
IInArchive,
IArchiveOpenSeq,
IOutArchive,
ISetProperties)
INTERFACE_IInArchive(;)
INTERFACE_IOutArchive(;)
STDMETHOD(OpenSeq)(ISequentialInStream *stream);
STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
CHandler() { }
};
static const Byte kProps[] =
{
kpidSize,
kpidPackSize
};
static const Byte kArcProps[] =
{
kpidNumStreams,
kpidNumBlocks
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /*propID*/, PROPVARIANT * /*value*/)
{
return S_OK;
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems = 1;
return S_OK;
}
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
{
NCOM::CPropVariant prop;
switch (propID)
{
case kpidPackSize: if (_packSize_Defined) prop = _packSize; break;
case kpidSize: if (_unpackSize_Defined) prop = _unpackSize; break;
}
prop.Detach(value);
return S_OK;
}
static const unsigned kSignatureCheckSize = 4;
API_FUNC_static_IsArc IsArc_lz5(const Byte *p, size_t size)
{
if (size < 4)
return k_IsArc_Res_NEED_MORE;
UInt32 magic = GetUi32(p);
// skippable frames
if (magic >= 0x184D2A50 && magic <= 0x184D2A5F) {
if (size < 16)
return k_IsArc_Res_NEED_MORE;
magic = GetUi32(p+12);
}
// Lz5 Magic
if (magic == 0x184D2205)
return k_IsArc_Res_YES;
return k_IsArc_Res_NO;
}
}
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *)
{
COM_TRY_BEGIN
Close();
{
Byte buf[kSignatureCheckSize];
RINOK(ReadStream_FALSE(stream, buf, kSignatureCheckSize));
if (IsArc_lz5(buf, kSignatureCheckSize) == k_IsArc_Res_NO)
return S_FALSE;
_isArc = true;
_stream = stream;
_seqStream = stream;
RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
}
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
{
Close();
_isArc = true;
_seqStream = stream;
return S_OK;
}
STDMETHODIMP CHandler::Close()
{
_isArc = false;
_dataAfterEnd = false;
_needMoreInput = false;
_packSize_Defined = false;
_unpackSize_Defined = false;
_packSize = 0;
_seqStream.Release();
_stream.Release();
return S_OK;
}
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
if (numItems == 0)
return S_OK;
if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
return E_INVALIDARG;
if (_packSize_Defined)
extractCallback->SetTotal(_packSize);
CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
if (!testMode && !realOutStream)
return S_OK;
extractCallback->PrepareOperation(askMode);
Int32 opRes;
{
NCompress::NLZ5::CDecoder *decoderSpec = new NCompress::NLZ5::CDecoder;
CMyComPtr<ICompressCoder> decoder = decoderSpec;
decoderSpec->SetInStream(_seqStream);
CDummyOutStream *outStreamSpec = new CDummyOutStream;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->SetStream(realOutStream);
outStreamSpec->Init();
realOutStream.Release();
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, true);
UInt64 packSize = 0;
UInt64 unpackedSize = 0;
HRESULT result = S_OK;
for (;;)
{
lps->InSize = packSize;
lps->OutSize = unpackedSize;
RINOK(lps->SetCur());
result = decoderSpec->CodeResume(outStream, &unpackedSize, progress);
UInt64 streamSize = decoderSpec->GetInputProcessedSize();
if (result != S_FALSE && result != S_OK)
return result;
if (unpackedSize == 0)
break;
if (streamSize == packSize)
{
// no new bytes in input stream, So it's good end of archive.
result = S_OK;
break;
}
if (packSize > streamSize)
return E_FAIL;
if (result != S_OK)
break;
}
decoderSpec->ReleaseInStream();
outStream.Release();
if (!_isArc)
opRes = NExtract::NOperationResult::kIsNotArc;
else if (_needMoreInput)
opRes = NExtract::NOperationResult::kUnexpectedEnd;
else if (_dataAfterEnd)
opRes = NExtract::NOperationResult::kDataAfterEnd;
else if (result == S_FALSE)
opRes = NExtract::NOperationResult::kDataError;
else if (result == S_OK)
opRes = NExtract::NOperationResult::kOK;
else
return result;
}
return extractCallback->SetOperationResult(opRes);
COM_TRY_END
}
static HRESULT UpdateArchive(
UInt64 unpackSize,
ISequentialOutStream *outStream,
const CProps &props,
IArchiveUpdateCallback *updateCallback)
{
RINOK(updateCallback->SetTotal(unpackSize));
CMyComPtr<ISequentialInStream> fileInStream;
RINOK(updateCallback->GetStream(0, &fileInStream));
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
localProgressSpec->Init(updateCallback, true);
NCompress::NLZ5::CEncoder *encoderSpec = new NCompress::NLZ5::CEncoder;
CMyComPtr<ICompressCoder> encoder = encoderSpec;
RINOK(props.SetCoderProps(encoderSpec, NULL));
RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress));
return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
}
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
{
*type = NFileTimeType::kUnix;
return S_OK;
}
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *updateCallback)
{
COM_TRY_BEGIN
if (numItems != 1)
return E_INVALIDARG;
Int32 newData, newProps;
UInt32 indexInArchive;
if (!updateCallback)
return E_FAIL;
RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive));
if ((newProps))
{
{
NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop));
if (prop.vt != VT_EMPTY)
if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE)
return E_INVALIDARG;
}
}
if ((newData))
{
UInt64 size;
{
NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(0, kpidSize, &prop));
if (prop.vt != VT_UI8)
return E_INVALIDARG;
size = prop.uhVal.QuadPart;
}
return UpdateArchive(size, outStream, _props, updateCallback);
}
if (indexInArchive != 0)
return E_INVALIDARG;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(updateCallback, true);
CMyComPtr<IArchiveUpdateCallbackFile> opCallback;
updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback);
if (opCallback)
{
RINOK(opCallback->ReportOperation(
NEventIndexType::kInArcIndex, 0,
NUpdateNotifyOp::kReplicate))
}
if (_stream)
RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
return NCompress::CopyStream(_stream, outStream, progress);
COM_TRY_END
}
STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
return _props.SetProperties(names, values, numProps);
}
static const Byte k_Signature[] = "0x184D2205";
REGISTER_ARC_IO(
"lz5", "lz5 tlz5", "* .tar", 0x10,
k_Signature,
0,
NArcInfoFlags::kKeepName,
IsArc_lz5)
}}

View File

@@ -0,0 +1,460 @@
// LzHandler.cpp
#include "StdAfx.h"
#include "../../../C/CpuArch.h"
#include "../../Common/ComTry.h"
#include "../../Common/IntToString.h"
#include "../../Windows/PropVariant.h"
#include "../Common/ProgressUtils.h"
#include "../Common/RegisterArc.h"
#include "../Common/StreamUtils.h"
#include "../Compress/LzmaDecoder.h"
#include "Common/OutStreamWithCRC.h"
using namespace NWindows;
namespace NArchive {
namespace NLz {
static const Byte kProps[] =
{
kpidSize,
kpidPackSize,
};
static const Byte kArcProps[] =
{
kpidNumStreams
};
static const Byte k_Signature[5] = { 'L', 'Z', 'I', 'P', 1 };
enum { k_SignatureSize = 5 };
struct CHeader
{
Byte data[6]; // 0-3 magic bytes, 4 version, 5 coded_dict_size
enum { size = 6 };
enum { min_dictionary_size = 1 << 12, max_dictionary_size = 1 << 29 };
unsigned DicSize;
Byte LzmaProps[5];
bool Parse();
};
struct CTrailer
{
Byte data[20]; // 0-3 CRC32 of the uncompressed data
// 4-11 size of the uncompressed data
// 12-19 member size including header and trailer
enum { size = 20 };
unsigned data_crc() const
{
unsigned tmp = 0;
for( int i = 3; i >= 0; --i ) { tmp <<= 8; tmp += data[i]; }
return tmp;
}
UInt64 data_size() const
{
UInt64 tmp = 0;
for( int i = 11; i >= 4; --i ) { tmp <<= 8; tmp += data[i]; }
return tmp;
}
UInt64 member_size() const
{
UInt64 tmp = 0;
for( int i = 19; i >= 12; --i ) { tmp <<= 8; tmp += data[i]; }
return tmp;
}
};
class CDecoder
{
CMyComPtr<ICompressCoder> _lzmaDecoder;
public:
NCompress::NLzma::CDecoder *_lzmaDecoderSpec;
~CDecoder();
HRESULT Create(ISequentialInStream *inStream);
HRESULT Code(const CHeader &header, ISequentialOutStream *outStream, ICompressProgressInfo *progress);
UInt64 GetInputProcessedSize() const { return _lzmaDecoderSpec->GetInputProcessedSize(); }
void ReleaseInStream() { if (_lzmaDecoder) _lzmaDecoderSpec->ReleaseInStream(); }
HRESULT ReadInput(Byte *data, UInt32 size, UInt32 *processedSize)
{ return _lzmaDecoderSpec->ReadFromInputStream(data, size, processedSize); }
};
HRESULT CDecoder::Create(ISequentialInStream *inStream)
{
if (!_lzmaDecoder)
{
_lzmaDecoderSpec = new NCompress::NLzma::CDecoder;
_lzmaDecoderSpec->FinishStream = true;
_lzmaDecoder = _lzmaDecoderSpec;
}
return _lzmaDecoderSpec->SetInStream(inStream);
}
CDecoder::~CDecoder()
{
ReleaseInStream();
}
HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream,
ICompressProgressInfo *progress)
{
{
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
_lzmaDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
if (!setDecoderProperties)
return E_NOTIMPL;
RINOK(setDecoderProperties->SetDecoderProperties2(header.LzmaProps, 5));
}
RINOK(_lzmaDecoderSpec->CodeResume(outStream, NULL, progress));
return S_OK;
}
class CHandler:
public IInArchive,
public IArchiveOpenSeq,
public CMyUnknownImp
{
CHeader _header;
CMyComPtr<IInStream> _stream;
CMyComPtr<ISequentialInStream> _seqStream;
bool _isArc;
bool _needSeekToStart;
bool _dataAfterEnd;
bool _needMoreInput;
bool _packSize_Defined;
bool _unpackSize_Defined;
bool _numStreams_Defined;
bool _dataError;
UInt64 _packSize;
UInt64 _unpackSize;
UInt64 _numStreams;
public:
MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq)
INTERFACE_IInArchive(;)
STDMETHOD(OpenSeq)(ISequentialInStream *stream);
CHandler() { }
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
NCOM::CPropVariant prop;
switch (propID)
{
case kpidPhySize: if (_packSize_Defined) prop = _packSize; break;
case kpidUnpackSize: if (_unpackSize_Defined) prop = _unpackSize; break;
case kpidNumStreams: if (_numStreams_Defined) prop = _numStreams; break;
case kpidErrorFlags:
{
UInt32 v = 0;
if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;;
if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd;
if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd;
if (_dataError) v |= kpv_ErrorFlags_DataError;
prop = v;
}
}
prop.Detach(value);
return S_OK;
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems = 1;
return S_OK;
}
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
{
NCOM::CPropVariant prop;
switch (propID)
{
case kpidSize: if (_unpackSize_Defined) prop = _unpackSize; break;
case kpidPackSize: if (_packSize_Defined) prop = _packSize; break;
}
prop.Detach(value);
return S_OK;
}
API_FUNC_static_IsArc IsArc_Lz(const Byte *p, size_t size)
{
if (size < k_SignatureSize)
return k_IsArc_Res_NEED_MORE;
for( int i = 0; i < k_SignatureSize; ++i )
if( p[i] != k_Signature[i] )
return k_IsArc_Res_NO;
return k_IsArc_Res_YES;
}
}
bool CHeader::Parse()
{
if (IsArc_Lz(data, k_SignatureSize) == k_IsArc_Res_NO)
return false;
DicSize = ( 1 << ( data[5] & 0x1F ) );
if( DicSize > min_dictionary_size )
DicSize -= ( DicSize / 16 ) * ( ( data[5] >> 5 ) & 7 );
LzmaProps[0] = 93; /* (45 * 2) + (9 * 0) + 3 */
unsigned ds = DicSize;
for( int i = 1; i <= 4; ++i ) { LzmaProps[i] = ds & 0xFF; ds >>= 8; }
return (DicSize >= min_dictionary_size && DicSize <= max_dictionary_size);
}
STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *)
{
Close();
RINOK(ReadStream_FALSE(inStream, _header.data, CHeader::size));
if (!_header.Parse())
return S_FALSE;
RINOK(inStream->Seek(0, STREAM_SEEK_END, &_packSize));
if (_packSize < 36)
return S_FALSE;
_isArc = true;
_stream = inStream;
_seqStream = inStream;
_needSeekToStart = true;
return S_OK;
}
STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
{
Close();
_isArc = true;
_seqStream = stream;
return S_OK;
}
STDMETHODIMP CHandler::Close()
{
_isArc = false;
_packSize_Defined = false;
_unpackSize_Defined = false;
_numStreams_Defined = false;
_dataAfterEnd = false;
_needMoreInput = false;
_dataError = false;
_packSize = 0;
_needSeekToStart = false;
_stream.Release();
_seqStream.Release();
return S_OK;
}
class CCompressProgressInfoImp:
public ICompressProgressInfo,
public CMyUnknownImp
{
CMyComPtr<IArchiveOpenCallback> Callback;
public:
UInt64 Offset;
MY_UNKNOWN_IMP1(ICompressProgressInfo)
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
void Init(IArchiveOpenCallback *callback) { Callback = callback; }
};
STDMETHODIMP CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)
{
if (Callback)
{
UInt64 files = 0;
UInt64 value = Offset + *inSize;
return Callback->SetCompleted(&files, &value);
}
return S_OK;
}
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
if (numItems == 0)
return S_OK;
if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
return E_INVALIDARG;
if (_packSize_Defined)
extractCallback->SetTotal(_packSize);
CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
if (!testMode && !realOutStream)
return S_OK;
extractCallback->PrepareOperation(askMode);
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->SetStream(realOutStream);
outStreamSpec->Init();
realOutStream.Release();
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, true);
if (_needSeekToStart)
{
if (!_stream)
return E_FAIL;
RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
}
else
_needSeekToStart = true;
CDecoder decoder;
HRESULT result = decoder.Create(_seqStream);
RINOK(result);
bool firstItem = true;
UInt64 packSize = 0;
UInt64 unpackSize = 0;
UInt64 numStreams = 0;
bool crcError = false;
bool dataAfterEnd = false;
for (;;)
{
lps->InSize = packSize;
lps->OutSize = unpackSize;
RINOK(lps->SetCur());
CHeader st;
UInt32 processed;
RINOK(decoder.ReadInput(st.data, CHeader::size, &processed));
if (processed != CHeader::size)
{
if (processed != 0)
dataAfterEnd = true;
break;
}
if (!st.Parse())
{
dataAfterEnd = true;
break;
}
numStreams++;
firstItem = false;
outStreamSpec->InitCRC();
result = decoder.Code(st, outStream, progress);
UInt64 member_size = decoder.GetInputProcessedSize() - packSize;
packSize += member_size;
UInt64 data_size = outStreamSpec->GetSize() - unpackSize;
unpackSize += data_size;
if (result == S_OK)
{
CTrailer trailer;
RINOK(decoder.ReadInput(trailer.data, CTrailer::size, &processed));
packSize += processed; member_size += processed;
if (processed != CTrailer::size ||
trailer.data_crc() != outStreamSpec->GetCRC() ||
trailer.data_size() != data_size ||
trailer.member_size() != member_size)
{
crcError = true;
result = S_FALSE;
break;
}
}
if (result == S_FALSE)
break;
RINOK(result);
}
if (firstItem)
{
_isArc = false;
result = S_FALSE;
}
else if (result == S_OK || result == S_FALSE)
{
if (dataAfterEnd)
_dataAfterEnd = true;
else if (decoder._lzmaDecoderSpec->NeedMoreInput)
_needMoreInput = true;
_packSize = packSize;
_unpackSize = unpackSize;
_numStreams = numStreams;
_packSize_Defined = true;
_unpackSize_Defined = true;
_numStreams_Defined = true;
}
Int32 opResult = NExtract::NOperationResult::kOK;
if (!_isArc)
opResult = NExtract::NOperationResult::kIsNotArc;
else if (_needMoreInput)
opResult = NExtract::NOperationResult::kUnexpectedEnd;
else if (crcError)
opResult = NExtract::NOperationResult::kCRCError;
else if (_dataAfterEnd)
opResult = NExtract::NOperationResult::kDataAfterEnd;
else if (result == S_FALSE)
opResult = NExtract::NOperationResult::kDataError;
else if (result == S_OK)
opResult = NExtract::NOperationResult::kOK;
else
return result;
outStream.Release();
return extractCallback->SetOperationResult(opResult);
COM_TRY_END
}
REGISTER_ARC_I(
"lzip", "lz tlz", "* .tar", 0xC6,
k_Signature,
0,
NArcInfoFlags::kKeepName,
IsArc_Lz)
}}

View File

@@ -17,8 +17,6 @@
#include "Common/DummyOutStream.h"
#include "Common/HandlerOut.h"
#include <stdio.h>
using namespace NWindows;
namespace NArchive {
@@ -109,6 +107,14 @@ API_FUNC_static_IsArc IsArc_zstd(const Byte *p, size_t size)
UInt32 magic = GetUi32(p);
// skippable frames
if (magic >= 0x184D2A50 && magic <= 0x184D2A5F) {
if (size < 16)
return k_IsArc_Res_NEED_MORE;
magic = GetUi32(p+12);
}
#ifdef ZSTD_LEGACY_SUPPORT
// zstd 0.1
if (magic == 0xFD2FB51E)
return k_IsArc_Res_YES;
@@ -116,10 +122,11 @@ API_FUNC_static_IsArc IsArc_zstd(const Byte *p, size_t size)
// zstd magic's for 0.2 .. 0.8 (aka 1.x)
if (magic >= 0xFD2FB522 && magic <= 0xFD2FB528)
return k_IsArc_Res_YES;
// skippable frames
if (magic >= 0x184D2A50 && magic <= 0x184D2A5F)
#else
/* only version 1.x */
if (magic == 0xFD2FB528)
return k_IsArc_Res_YES;
#endif
return k_IsArc_Res_NO;
}
@@ -223,10 +230,6 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
result = decoderSpec->CodeResume(outStream, &unpackedSize, progress);
UInt64 streamSize = decoderSpec->GetInputProcessedSize();
printf("streamsize=%d packsize=%d unpackedSize=%d\n",
streamSize, packSize, unpackedSize);
fflush(stdout);
if (result != S_FALSE && result != S_OK)
return result;
@@ -362,7 +365,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
return _props.SetProperties(names, values, numProps);
}
static const Byte k_Signature[] = "0xFD2FB525..0xFD2FB528";
static const Byte k_Signature[] = "0xFD2FB522..28";
REGISTER_ARC_IO(
"zstd", "zst tzstd", "* .tar", 0x0e,

View File

@@ -1618,6 +1618,10 @@ SOURCE=..\..\Archive\IArchive.h
# End Source File
# Begin Source File
SOURCE=..\..\Archive\LzHandler.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\LzmaHandler.cpp
# End Source File
# Begin Source File

View File

@@ -70,6 +70,7 @@ AR_OBJS = \
$O\Bz2Handler.obj \
$O\DeflateProps.obj \
$O\GzHandler.obj \
$O\LzHandler.obj \
$O\LzmaHandler.obj \
$O\SplitHandler.obj \
$O\XzHandler.obj \

View File

@@ -0,0 +1,3 @@
// StdAfx.cpp
#include "StdAfx.h"

View File

@@ -0,0 +1,8 @@
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../../Common/Common.h"
#endif

View File

@@ -0,0 +1,36 @@
PROG = lz4.dll
DEF_FILE = ../../Compress/Codec.def
CFLAGS = $(CFLAGS) -DNEED_7ZIP_GUID
7ZIP_COMMON_OBJS = \
$O\StreamUtils.obj \
WIN_OBJS = \
$O\System.obj \
COMPRESS_OBJS = \
$O\CodecExports.obj \
$O\DllExportsCompress.obj \
C_OBJS = \
$O\Alloc.obj \
$O\Threads.obj \
COMPRESS_OBJS = $(COMPRESS_OBJS) \
$O\Lz4Decoder.obj \
$O\Lz4Encoder.obj \
$O\Lz4Register.obj \
LZ4_OBJS = \
$O\lz4.obj \
$O\lz4frame.obj \
$O\lz4hc.obj \
$O\lz4xxhash.obj \
ZSTDMT_OBJS = \
$O\lz4mt_common.obj \
$O\lz4mt_compress.obj \
$O\lz4mt_decompress.obj \
$O\threading.obj \
!include "../../7zip.mak"

View File

@@ -0,0 +1,6 @@
#include "../../../../C/7zVersionTr.h"
#include "../../../../C/7zVersion.rc"
MY_VERSION_INFO_DLL("7z LZ4 Plugin", "lz4")
101 ICON "../../Archive/Icons/7z.ico"

View File

@@ -0,0 +1,3 @@
// StdAfx.cpp
#include "StdAfx.h"

View File

@@ -0,0 +1,8 @@
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../../Common/Common.h"
#endif

View File

@@ -0,0 +1,36 @@
PROG = lz5.dll
DEF_FILE = ../../Compress/Codec.def
CFLAGS = $(CFLAGS) -DNEED_7ZIP_GUID
7ZIP_COMMON_OBJS = \
$O\StreamUtils.obj \
WIN_OBJS = \
$O\System.obj \
COMPRESS_OBJS = \
$O\CodecExports.obj \
$O\DllExportsCompress.obj \
C_OBJS = \
$O\Alloc.obj \
$O\Threads.obj \
COMPRESS_OBJS = $(COMPRESS_OBJS) \
$O\Lz5Decoder.obj \
$O\Lz5Encoder.obj \
$O\Lz5Register.obj \
LZ5_OBJS = \
$O\lz5.obj \
$O\lz5frame.obj \
$O\lz5hc.obj \
$O\lz5xxhash.obj \
ZSTDMT_OBJS = \
$O\lz5mt_common.obj \
$O\lz5mt_compress.obj \
$O\lz5mt_decompress.obj \
$O\threading.obj \
!include "../../7zip.mak"

View File

@@ -0,0 +1,6 @@
#include "../../../../C/7zVersionTr.h"
#include "../../../../C/7zVersion.rc"
MY_VERSION_INFO_DLL("7z LZ5 Plugin", "lz5")
101 ICON "../../Archive/Icons/7z.ico"

View File

@@ -5,17 +5,38 @@ CFLAGS = $(CFLAGS) -DNEED_7ZIP_GUID
7ZIP_COMMON_OBJS = \
$O\StreamUtils.obj \
WIN_OBJS = \
$O\System.obj \
COMPRESS_OBJS = \
$O\CodecExports.obj \
$O\DllExportsCompress.obj \
C_OBJS = \
$O\Alloc.obj \
$O\Threads.obj \
!include "../../zstd.mak"
ZSTD_OBJS = $(ZSTD_OBJS) \
COMPRESS_OBJS = $(COMPRESS_OBJS) \
$O\ZstdDecoder.obj \
$O\ZstdEncoder.obj \
$O\ZstdRegister.obj \
ZSTD_OBJS = \
$O\entropy_common.obj \
$O\fse_decompress.obj \
$O\huf_decompress.obj \
$O\zstd_common.obj \
$O\zstd_decompress.obj \
$O\xxhash.obj \
$O\fse_compress.obj \
$O\huf_compress.obj \
$O\zstd_compress.obj \
$O\error_private.obj \
ZSTDMT_OBJS = \
$O\threading.obj \
$O\zstdmt_common.obj \
$O\zstdmt_compress.obj \
$O\zstdmt_decompress.obj \
!include "../../7zip.mak"

View File

@@ -5,18 +5,33 @@ CFLAGS = $(CFLAGS) -DNEED_7ZIP_GUID -DZSTD_LEGACY_SUPPORT
7ZIP_COMMON_OBJS = \
$O\StreamUtils.obj \
WIN_OBJS = \
$O\System.obj \
COMPRESS_OBJS = \
$O\CodecExports.obj \
$O\DllExportsCompress.obj \
C_OBJS = \
$O\Alloc.obj \
$O\Threads.obj \
!include "../../zstd.mak"
ZSTD_OBJS = $(ZSTD_OBJS) \
COMPRESS_OBJS = $(COMPRESS_OBJS) \
$O\ZstdDecoder.obj \
$O\ZstdEncoder.obj \
$O\ZstdRegister.obj \
ZSTD_OBJS = \
$O\entropy_common.obj \
$O\fse_decompress.obj \
$O\huf_decompress.obj \
$O\zstd_common.obj \
$O\zstd_decompress.obj \
$O\xxhash.obj \
$O\fse_compress.obj \
$O\huf_compress.obj \
$O\zstd_compress.obj \
$O\error_private.obj \
$O\zstd_v01.obj \
$O\zstd_v02.obj \
$O\zstd_v03.obj \
@@ -25,4 +40,10 @@ ZSTD_OBJS = $(ZSTD_OBJS) \
$O\zstd_v06.obj \
$O\zstd_v07.obj \
ZSTDMT_OBJS = \
$O\threading.obj \
$O\zstdmt_common.obj \
$O\zstdmt_compress.obj \
$O\zstdmt_decompress.obj \
!include "../../7zip.mak"

View File

@@ -3,5 +3,5 @@
STRINGTABLE
BEGIN
100 "7z zip rar 001 cab iso xz txz lzma tar cpio bz2 bzip2 tbz2 tbz gz gzip tgz tpz z taz lzh lha rpm deb arj vhd wim swm fat ntfs dmg hfs xar squashfs"
100 "7z zip rar 001 cab iso xz txz lzma tar cpio bz2 bzip2 tbz2 tbz gz gzip tgz tpz z taz lz tlz lz4 tlz4 lz5 tlz5 lzh lha rpm deb arj vhd wim swm fat ntfs dmg hfs xar squashfs zst"
END

View File

@@ -136,10 +136,28 @@ C_OBJS = \
!include "../../Aes.mak"
!include "../../Crc.mak"
!include "../../zstd.mak"
ZSTD_OBJS = $(ZSTD_OBJS) \
COMPRESS_OBJS = $(COMPRESS_OBJS) \
$O\ZstdDecoder.obj \
$O\ZstdEncoder.obj \
$O\ZstdRegister.obj \
ZSTD_OBJS = \
$O\entropy_common.obj \
$O\fse_decompress.obj \
$O\huf_decompress.obj \
$O\zstd_common.obj \
$O\zstd_decompress.obj \
$O\xxhash.obj \
$O\fse_compress.obj \
$O\huf_compress.obj \
$O\zstd_compress.obj \
$O\error_private.obj \
ZSTDMT_OBJS = \
$O\threading.obj \
$O\zstdmt_common.obj \
$O\zstdmt_compress.obj \
$O\zstdmt_decompress.obj \
!include "../../7zip.mak"

View File

@@ -69,6 +69,9 @@ AR_OBJS = \
$O\HandlerCont.obj \
$O\HfsHandler.obj \
$O\IhexHandler.obj \
$O\LzHandler.obj \
$O\Lz4Handler.obj \
$O\Lz5Handler.obj \
$O\LzhHandler.obj \
$O\LzmaHandler.obj \
$O\MachoHandler.obj \
@@ -104,7 +107,6 @@ AR_COMMON_OBJS = \
$O\HandlerOut.obj \
$O\ParseProperties.obj \
7Z_OBJS = \
$O\7zCompressionMode.obj \
$O\7zDecode.obj \
@@ -242,7 +244,6 @@ CRYPTO_OBJS = \
$O\ZipCrypto.obj \
$O\ZipStrong.obj \
C_OBJS = \
$O\7zBuf2.obj \
$O\7zStream.obj \

View File

@@ -16,12 +16,39 @@ AR_OBJS = $(AR_OBJS) \
$O\ArchiveExports.obj \
$O\DllExports2.obj \
COMPRESS_OBJS = $(COMPRESS_OBJS) \
$O\Lz4Decoder.obj \
$O\Lz4Encoder.obj \
$O\Lz4Register.obj \
$O\Lz5Decoder.obj \
$O\Lz5Encoder.obj \
$O\Lz5Register.obj \
$O\ZstdDecoder.obj \
$O\ZstdEncoder.obj \
$O\ZstdRegister.obj \
!include "../../zstd.mak"
ZSTD_OBJS = $(ZSTD_OBJS) \
LZ4_OBJS = \
$O\lz4.obj \
$O\lz4frame.obj \
$O\lz4hc.obj \
$O\lz4xxhash.obj \
LZ5_OBJS = \
$O\lz5.obj \
$O\lz5frame.obj \
$O\lz5hc.obj \
ZSTD_OBJS = \
$O\entropy_common.obj \
$O\fse_decompress.obj \
$O\huf_decompress.obj \
$O\zstd_common.obj \
$O\zstd_decompress.obj \
$O\xxhash.obj \
$O\fse_compress.obj \
$O\huf_compress.obj \
$O\zstd_compress.obj \
$O\error_private.obj \
$O\zstd_v01.obj \
$O\zstd_v02.obj \
$O\zstd_v03.obj \
@@ -30,4 +57,16 @@ ZSTD_OBJS = $(ZSTD_OBJS) \
$O\zstd_v06.obj \
$O\zstd_v07.obj \
ZSTDMT_OBJS = \
$O\lz5mt_common.obj \
$O\lz5mt_compress.obj \
$O\lz5mt_decompress.obj \
$O\lz4mt_common.obj \
$O\lz4mt_compress.obj \
$O\lz4mt_decompress.obj \
$O\threading.obj \
$O\zstdmt_common.obj \
$O\zstdmt_compress.obj \
$O\zstdmt_decompress.obj \
!include "../../7zip.mak"

View File

@@ -29,9 +29,11 @@ MY_VERSION_INFO_DLL("7z Plugin", "7z")
23 ICON "../../Archive/Icons/xz.ico"
24 ICON "../../Archive/Icons/squashfs.ico"
25 ICON "../../Archive/Icons/zst.ico"
26 ICON "../../Archive/Icons/lz4.ico"
27 ICON "../../Archive/Icons/lz5.ico"
STRINGTABLE
BEGIN
100 "7z:0 zip:1 rar:3 001:9 cab:7 iso:8 xz:23 txz:23 lzma:16 tar:13 cpio:12 bz2:2 bzip2:2 tbz2:2 tbz:2 gz:14 gzip:14 tgz:14 tpz:14 z:5 taz:5 lzh:6 lha:6 rpm:10 deb:11 arj:4 vhd:20 wim:15 swm:15 fat:21 ntfs:22 dmg:17 hfs:18 xar:19 squashfs:24 zst:25"
100 "7z:0 zip:1 rar:3 001:9 cab:7 iso:8 xz:23 txz:23 lzma:16 tar:13 cpio:12 bz2:2 bzip2:2 tbz2:2 tbz:2 gz:14 gzip:14 tgz:14 tpz:14 z:5 taz:5 lz:16 tlz:16 lz4:26 lz5:27 lzh:6 lha:6 rpm:10 deb:11 arj:4 vhd:20 wim:15 swm:15 fat:21 ntfs:22 dmg:17 hfs:18 xar:19 squashfs:24 zst:25"
END

View File

@@ -41,6 +41,7 @@ WIN_OBJS = \
$O\PropVariant.obj \
$O\PropVariantConv.obj \
$O\Synchronization.obj \
$O\System.obj \
7ZIP_COMMON_OBJS = \
$O\CreateCoder.obj \
@@ -126,5 +127,22 @@ C_OBJS = \
!include "../../Aes.mak"
!include "../../Crc.mak"
!include "../../zstd.mak"
COMPRESS_OBJS = $(COMPRESS_OBJS) \
$O\ZstdDecoder.obj \
$O\ZstdRegister.obj \
ZSTD_OBJS = \
$O\entropy_common.obj \
$O\fse_decompress.obj \
$O\huf_decompress.obj \
$O\zstd_common.obj \
$O\zstd_decompress.obj \
$O\xxhash.obj \
$O\error_private.obj \
ZSTDMT_OBJS = \
$O\threading.obj \
$O\zstdmt_common.obj \
$O\zstdmt_decompress.obj \
!include "../../7zip.mak"

View File

@@ -106,6 +106,4 @@ C_OBJS = \
$O\Threads.obj \
!include "../../Crc.mak"
!include "../../zstd.mak"
!include "../../7zip.mak"

View File

@@ -40,6 +40,7 @@ WIN_OBJS = \
$O\PropVariantConv.obj \
$O\ResourceString.obj \
$O\Shell.obj \
$O\System.obj \
$O\Synchronization.obj \
$O\Window.obj \
@@ -144,5 +145,22 @@ C_OBJS = \
!include "../../Aes.mak"
!include "../../Crc.mak"
!include "../../zstd.mak"
COMPRESS_OBJS = $(COMPRESS_OBJS) \
$O\ZstdDecoder.obj \
$O\ZstdRegister.obj \
ZSTD_OBJS = \
$O\entropy_common.obj \
$O\fse_decompress.obj \
$O\huf_decompress.obj \
$O\zstd_common.obj \
$O\zstd_decompress.obj \
$O\xxhash.obj \
$O\error_private.obj \
ZSTDMT_OBJS = \
$O\threading.obj \
$O\zstdmt_common.obj \
$O\zstdmt_decompress.obj \
!include "../../7zip.mak"

View File

@@ -0,0 +1,177 @@
// (C) 2016 Tino Reichardt
#include "StdAfx.h"
#include "Lz4Decoder.h"
int Lz4Read(void *arg, LZ4MT_Buffer * in)
{
struct Lz4Stream *x = (struct Lz4Stream*)arg;
size_t size = in->size;
HRESULT res = ReadStream(x->inStream, in->buf, &size);
if (res != S_OK)
return -1;
in->size = size;
*x->processedIn += size;
return 0;
}
int Lz4Write(void *arg, LZ4MT_Buffer * out)
{
struct Lz4Stream *x = (struct Lz4Stream*)arg;
UInt32 todo = (UInt32)out->size;
UInt32 done = 0;
while (todo != 0)
{
UInt32 block;
HRESULT res = x->outStream->Write((char*)out->buf + done, todo, &block);
done += block;
if (res == k_My_HRESULT_WritingWasCut)
break;
if (res != S_OK)
return -1;
if (block == 0)
return E_FAIL;
todo -= block;
}
*x->processedOut += done;
if (x->progress)
x->progress->SetRatioInfo(x->processedIn, x->processedOut);
return 0;
}
namespace NCompress {
namespace NLZ4 {
CDecoder::CDecoder():
_processedIn(0),
_processedOut(0),
_inputSize(0),
_numThreads(NWindows::NSystem::GetNumberOfProcessors())
{
_props.clear();
}
CDecoder::~CDecoder()
{
}
HRESULT CDecoder::ErrorOut(size_t code)
{
const char *strError = LZ4MT_getErrorString(code);
wchar_t wstrError[200+5]; /* no malloc here, /TR */
mbstowcs(wstrError, strError, 200);
MessageBoxW(0, wstrError, L"7-Zip ZStandard", MB_ICONERROR | MB_OK);
MyFree(wstrError);
return S_FALSE;
}
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte * prop, UInt32 size)
{
DProps *pProps = (DProps *)prop;
if (size != sizeof(DProps))
return E_FAIL;
memcpy(&_props, pProps, sizeof (DProps));
return S_OK;
}
STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads)
{
const UInt32 kNumThreadsMax = LZ4MT_THREAD_MAX;
if (numThreads < 1) numThreads = 1;
if (numThreads > kNumThreadsMax) numThreads = kNumThreadsMax;
_numThreads = numThreads;
return S_OK;
}
HRESULT CDecoder::SetOutStreamSizeResume(const UInt64 * /*outSize*/)
{
_processedOut = 0;
return S_OK;
}
STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 * outSize)
{
_processedIn = 0;
RINOK(SetOutStreamSizeResume(outSize));
return S_OK;
}
HRESULT CDecoder::CodeSpec(ISequentialInStream * inStream,
ISequentialOutStream * outStream, ICompressProgressInfo * progress)
{
LZ4MT_RdWr_t rdwr;
size_t result;
HRESULT res = S_OK;
struct Lz4Stream Rd;
Rd.inStream = inStream;
Rd.processedIn = &_processedIn;
struct Lz4Stream Wr;
Wr.progress = progress;
Wr.outStream = outStream;
Wr.processedIn = &_processedIn;
Wr.processedOut = &_processedOut;
/* 1) setup read/write functions */
rdwr.fn_read = ::Lz4Read;
rdwr.fn_write = ::Lz4Write;
rdwr.arg_read = (void *)&Rd;
rdwr.arg_write = (void *)&Wr;
/* 2) create compression context */
LZ4MT_DCtx *ctx = LZ4MT_createDCtx(_numThreads, _inputSize);
if (!ctx)
return S_FALSE;
/* 3) compress */
result = LZ4MT_DecompressDCtx(ctx, &rdwr);
if (result == (size_t)-LZ4MT_error_read_fail)
res = E_ABORT;
else if (LZ4MT_isError(result))
return ErrorOut(result);
/* 4) free resources */
LZ4MT_freeDCtx(ctx);
return res;
}
STDMETHODIMP CDecoder::Code(ISequentialInStream * inStream, ISequentialOutStream * outStream,
const UInt64 * /*inSize */, const UInt64 *outSize, ICompressProgressInfo * progress)
{
SetOutStreamSize(outSize);
return CodeSpec(inStream, outStream, progress);
}
#ifndef NO_READ_FROM_CODER
STDMETHODIMP CDecoder::SetInStream(ISequentialInStream * inStream)
{
_inStream = inStream;
return S_OK;
}
STDMETHODIMP CDecoder::ReleaseInStream()
{
_inStream.Release();
return S_OK;
}
#endif
HRESULT CDecoder::CodeResume(ISequentialOutStream * outStream, const UInt64 * outSize, ICompressProgressInfo * progress)
{
RINOK(SetOutStreamSizeResume(outSize));
return CodeSpec(_inStream, outStream, progress);
}
}}

View File

@@ -0,0 +1,99 @@
// (C) 2016 Tino Reichardt
/**
* you can define LZ4_LEGACY_SUPPORT to be backwards compatible (0.1 .. 0.7)
* /TR 2016-10-01
*/
#define LZ4_STATIC_LINKING_ONLY
#include "../../../C/Alloc.h"
#include "../../../C/Threads.h"
#include "../../../C/lz4/lz4.h"
#include "../../../C/zstdmt/lz4mt.h"
#include "../../Windows/System.h"
#include "../../Common/Common.h"
#include "../../Common/MyCom.h"
#include "../ICoder.h"
#include "../Common/StreamUtils.h"
#include "../Common/RegisterCodec.h"
#include "../Common/ProgressMt.h"
struct Lz4Stream {
ISequentialInStream *inStream;
ISequentialOutStream *outStream;
ICompressProgressInfo *progress;
UInt64 *processedIn;
UInt64 *processedOut;
CCriticalSection *cs;
int flags;
};
extern int Lz4Read(void *Stream, LZ4MT_Buffer * in);
extern int Lz4Write(void *Stream, LZ4MT_Buffer * in);
namespace NCompress {
namespace NLZ4 {
struct DProps
{
DProps() { clear (); }
void clear ()
{
memset(this, 0, sizeof (*this));
_ver_major = LZ4_VERSION_MAJOR;
_ver_minor = LZ4_VERSION_MINOR;
_level = 1;
}
Byte _ver_major;
Byte _ver_minor;
Byte _level;
Byte _reserved[2];
};
class CDecoder:public ICompressCoder,
public ICompressSetDecoderProperties2,
public CMyUnknownImp
{
CMyComPtr < ISequentialInStream > _inStream;
DProps _props;
CCriticalSection cs;
UInt64 _processedIn;
UInt64 _processedOut;
UInt32 _inputSize;
UInt32 _numThreads;
HRESULT CDecoder::ErrorOut(size_t code);
HRESULT CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress);
HRESULT SetOutStreamSizeResume(const UInt64 *outSize);
public:
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2)
#ifndef NO_READ_FROM_CODER
MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
#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 (SetOutStreamSize)(const UInt64 *outSize);
STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads);
#ifndef NO_READ_FROM_CODER
STDMETHOD (SetInStream)(ISequentialInStream *inStream);
STDMETHOD (ReleaseInStream)();
UInt64 GetInputProcessedSize() const { return _processedIn; }
#endif
HRESULT CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress);
CDecoder();
virtual ~CDecoder();
};
}}

View File

@@ -0,0 +1,139 @@
// (C) 2016 Tino Reichardt
#include "StdAfx.h"
#include "Lz4Encoder.h"
#include "Lz4Decoder.h"
#ifndef EXTRACT_ONLY
namespace NCompress {
namespace NLZ4 {
CEncoder::CEncoder():
_processedIn(0),
_processedOut(0),
_inputSize(0),
_ctx(NULL),
_numThreads(NWindows::NSystem::GetNumberOfProcessors())
{
_props.clear();
}
CEncoder::~CEncoder()
{
if (_ctx)
LZ4MT_freeCCtx(_ctx);
}
STDMETHODIMP CEncoder::SetCoderProperties(const PROPID * propIDs, const PROPVARIANT * coderProps, UInt32 numProps)
{
_props.clear();
for (UInt32 i = 0; i < numProps; i++)
{
const PROPVARIANT & prop = coderProps[i];
PROPID propID = propIDs[i];
UInt32 v = (UInt32)prop.ulVal;
switch (propID)
{
case NCoderPropID::kLevel:
{
if (prop.vt != VT_UI4)
return E_INVALIDARG;
_props._level = static_cast < Byte > (prop.ulVal);
Byte lz4_level = static_cast < Byte > (LZ4MT_LEVEL_MAX);
if (_props._level > lz4_level)
_props._level = lz4_level;
break;
}
case NCoderPropID::kNumThreads:
{
SetNumberOfThreads(v);
break;
}
default:
{
break;
}
}
}
return S_OK;
}
STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream * outStream)
{
return WriteStream(outStream, &_props, sizeof (_props));
}
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UInt64 * /*inSize*/ ,
const UInt64 * /*outSize */, ICompressProgressInfo *progress)
{
LZ4MT_RdWr_t rdwr;
size_t result;
HRESULT res = S_OK;
struct Lz4Stream Rd;
Rd.inStream = inStream;
Rd.outStream = outStream;
Rd.processedIn = &_processedIn;
Rd.processedOut = &_processedOut;
struct Lz4Stream Wr;
if (_processedIn == 0)
Wr.progress = progress;
else
Wr.progress = 0;
Wr.inStream = inStream;
Wr.outStream = outStream;
Wr.processedIn = &_processedIn;
Wr.processedOut = &_processedOut;
/* 1) setup read/write functions */
rdwr.fn_read = ::Lz4Read;
rdwr.fn_write = ::Lz4Write;
rdwr.arg_read = (void *)&Rd;
rdwr.arg_write = (void *)&Wr;
/* 2) create compression context, if needed */
if (!_ctx)
_ctx = LZ4MT_createCCtx(_numThreads, _props._level, _inputSize);
if (!_ctx)
return S_FALSE;
/* 3) compress */
result = LZ4MT_CompressCCtx(_ctx, &rdwr);
if (result == (size_t)-LZ4MT_error_read_fail)
res = E_ABORT;
else if (LZ4MT_isError(result))
if (result != LZ4MT_error_read_fail)
return ErrorOut(result);
return res;
}
STDMETHODIMP CEncoder::SetNumberOfThreads(UInt32 numThreads)
{
const UInt32 kNumThreadsMax = LZ4MT_THREAD_MAX;
if (numThreads < 1) numThreads = 1;
if (numThreads > kNumThreadsMax) numThreads = kNumThreadsMax;
_numThreads = numThreads;
return S_OK;
}
HRESULT CEncoder::ErrorOut(size_t code)
{
const char *strError = LZ4MT_getErrorString(code);
wchar_t wstrError[200+5]; /* no malloc here, /TR */
mbstowcs(wstrError, strError, 200);
MessageBoxW(0, wstrError, L"7-Zip ZStandard", MB_ICONERROR | MB_OK);
MyFree(wstrError);
return S_FALSE;
}
}}
#endif

View File

@@ -0,0 +1,63 @@
// (C) 2016 Tino Reichardt
#define LZ4_STATIC_LINKING_ONLY
#include "../../../C/Alloc.h"
#include "../../../C/Threads.h"
#include "../../../C/lz4/lz4.h"
#include "../../../C/zstdmt/lz4mt.h"
#include "../../Common/Common.h"
#include "../../Common/MyCom.h"
#include "../ICoder.h"
#include "../Common/StreamUtils.h"
#ifndef EXTRACT_ONLY
namespace NCompress {
namespace NLZ4 {
struct CProps
{
CProps() { clear (); }
void clear ()
{
memset(this, 0, sizeof (*this));
_ver_major = LZ4_VERSION_MAJOR;
_ver_minor = LZ4_VERSION_MINOR;
_level = 3;
}
Byte _ver_major;
Byte _ver_minor;
Byte _level;
Byte _reserved[2];
};
class CEncoder:
public ICompressCoder,
public ICompressSetCoderProperties,
public ICompressWriteCoderProperties,
public CMyUnknownImp
{
CProps _props;
UInt64 _processedIn;
UInt64 _processedOut;
UInt32 _inputSize;
UInt32 _numThreads;
LZ4MT_CCtx *_ctx;
HRESULT CEncoder::ErrorOut(size_t code);
public:
MY_UNKNOWN_IMP2 (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);
STDMETHODIMP CEncoder::SetNumberOfThreads(UInt32 numThreads);
CEncoder();
virtual ~CEncoder();
};
}}
#endif

View File

@@ -0,0 +1,17 @@
// (C) 2016 Tino Reichardt
#include "StdAfx.h"
#include "../Common/RegisterCodec.h"
#include "Lz4Decoder.h"
#ifndef EXTRACT_ONLY
#include "Lz4Encoder.h"
#endif
REGISTER_CODEC_E(
LZ4,
NCompress::NLZ4::CDecoder(),
NCompress::NLZ4::CEncoder(),
0x4F71104, "LZ4")

View File

@@ -0,0 +1,178 @@
// (C) 2016 Tino Reichardt
#include "StdAfx.h"
#include "Lz5Decoder.h"
int Lz5Read(void *arg, LZ5MT_Buffer * in)
{
struct Lz5Stream *x = (struct Lz5Stream*)arg;
size_t size = in->size;
HRESULT res = ReadStream(x->inStream, in->buf, &size);
if (res != S_OK)
return -1;
in->size = size;
*x->processedIn += size;
return 0;
}
int Lz5Write(void *arg, LZ5MT_Buffer * out)
{
struct Lz5Stream *x = (struct Lz5Stream*)arg;
UInt32 todo = (UInt32)out->size;
UInt32 done = 0;
while (todo != 0)
{
UInt32 block;
HRESULT res = x->outStream->Write((char*)out->buf + done, todo, &block);
done += block;
if (res == k_My_HRESULT_WritingWasCut)
break;
if (res != S_OK)
return -1;
if (block == 0)
return E_FAIL;
todo -= block;
}
*x->processedOut += done;
if (x->progress)
x->progress->SetRatioInfo(x->processedIn, x->processedOut);
return 0;
}
namespace NCompress {
namespace NLZ5 {
CDecoder::CDecoder():
_processedIn(0),
_processedOut(0),
_inputSize(0),
_numThreads(NWindows::NSystem::GetNumberOfProcessors())
{
_props.clear();
}
CDecoder::~CDecoder()
{
}
HRESULT CDecoder::ErrorOut(size_t code)
{
const char *strError = LZ5MT_getErrorString(code);
wchar_t wstrError[200+5]; /* no malloc here, /TR */
mbstowcs(wstrError, strError, 200);
MessageBoxW(0, wstrError, L"7-Zip ZStandard", MB_ICONERROR | MB_OK);
MyFree(wstrError);
return S_FALSE;
}
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte * prop, UInt32 size)
{
DProps *pProps = (DProps *)prop;
if (size != sizeof(DProps))
return E_FAIL;
memcpy(&_props, pProps, sizeof (DProps));
return S_OK;
}
STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads)
{
const UInt32 kNumThreadsMax = LZ5MT_THREAD_MAX;
if (numThreads < 1) numThreads = 1;
if (numThreads > kNumThreadsMax) numThreads = kNumThreadsMax;
_numThreads = numThreads;
return S_OK;
}
HRESULT CDecoder::SetOutStreamSizeResume(const UInt64 * /*outSize*/)
{
_processedOut = 0;
return S_OK;
}
STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 * outSize)
{
_processedIn = 0;
RINOK(SetOutStreamSizeResume(outSize));
return S_OK;
}
HRESULT CDecoder::CodeSpec(ISequentialInStream * inStream,
ISequentialOutStream * outStream, ICompressProgressInfo * progress)
{
LZ5MT_RdWr_t rdwr;
size_t result;
HRESULT res = S_OK;
struct Lz5Stream Rd;
Rd.inStream = inStream;
Rd.processedIn = &_processedIn;
struct Lz5Stream Wr;
Wr.progress = progress;
Wr.outStream = outStream;
Wr.processedIn = &_processedIn;
Wr.processedOut = &_processedOut;
/* 1) setup read/write functions */
rdwr.fn_read = ::Lz5Read;
rdwr.fn_write = ::Lz5Write;
rdwr.arg_read = (void *)&Rd;
rdwr.arg_write = (void *)&Wr;
/* 2) create compression context */
LZ5MT_DCtx *ctx = LZ5MT_createDCtx(_numThreads, _inputSize);
if (!ctx)
return S_FALSE;
/* 3) compress */
result = LZ5MT_DecompressDCtx(ctx, &rdwr);
if (result == (size_t)-LZ5MT_error_read_fail)
res = E_ABORT;
else if (LZ5MT_isError(result))
if (result != LZ5MT_error_read_fail)
return ErrorOut(result);
/* 4) free resources */
LZ5MT_freeDCtx(ctx);
return res;
}
STDMETHODIMP CDecoder::Code(ISequentialInStream * inStream, ISequentialOutStream * outStream,
const UInt64 * /*inSize */, const UInt64 *outSize, ICompressProgressInfo * progress)
{
SetOutStreamSize(outSize);
return CodeSpec(inStream, outStream, progress);
}
#ifndef NO_READ_FROM_CODER
STDMETHODIMP CDecoder::SetInStream(ISequentialInStream * inStream)
{
_inStream = inStream;
return S_OK;
}
STDMETHODIMP CDecoder::ReleaseInStream()
{
_inStream.Release();
return S_OK;
}
#endif
HRESULT CDecoder::CodeResume(ISequentialOutStream * outStream, const UInt64 * outSize, ICompressProgressInfo * progress)
{
RINOK(SetOutStreamSizeResume(outSize));
return CodeSpec(_inStream, outStream, progress);
}
}}

View File

@@ -0,0 +1,99 @@
// (C) 2016 Tino Reichardt
/**
* you can define LZ5_LEGACY_SUPPORT to be backwards compatible (0.1 .. 0.7)
* /TR 2016-10-01
*/
#define LZ5_STATIC_LINKING_ONLY
#include "../../../C/Alloc.h"
#include "../../../C/Threads.h"
#include "../../../C/lz5/lz5.h"
#include "../../../C/zstdmt/lz5mt.h"
#include "../../Windows/System.h"
#include "../../Common/Common.h"
#include "../../Common/MyCom.h"
#include "../ICoder.h"
#include "../Common/StreamUtils.h"
#include "../Common/RegisterCodec.h"
#include "../Common/ProgressMt.h"
struct Lz5Stream {
ISequentialInStream *inStream;
ISequentialOutStream *outStream;
ICompressProgressInfo *progress;
UInt64 *processedIn;
UInt64 *processedOut;
CCriticalSection *cs;
int flags;
};
extern int Lz5Read(void *Stream, LZ5MT_Buffer * in);
extern int Lz5Write(void *Stream, LZ5MT_Buffer * in);
namespace NCompress {
namespace NLZ5 {
struct DProps
{
DProps() { clear (); }
void clear ()
{
memset(this, 0, sizeof (*this));
_ver_major = LZ5_VERSION_MAJOR;
_ver_minor = LZ5_VERSION_MINOR;
_level = 1;
}
Byte _ver_major;
Byte _ver_minor;
Byte _level;
Byte _reserved[2];
};
class CDecoder:public ICompressCoder,
public ICompressSetDecoderProperties2,
public CMyUnknownImp
{
CMyComPtr < ISequentialInStream > _inStream;
DProps _props;
CCriticalSection cs;
UInt64 _processedIn;
UInt64 _processedOut;
UInt32 _inputSize;
UInt32 _numThreads;
HRESULT CDecoder::ErrorOut(size_t code);
HRESULT CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress);
HRESULT SetOutStreamSizeResume(const UInt64 *outSize);
public:
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2)
#ifndef NO_READ_FROM_CODER
MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
#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 (SetOutStreamSize)(const UInt64 *outSize);
STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads);
#ifndef NO_READ_FROM_CODER
STDMETHOD (SetInStream)(ISequentialInStream *inStream);
STDMETHOD (ReleaseInStream)();
UInt64 GetInputProcessedSize() const { return _processedIn; }
#endif
HRESULT CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress);
CDecoder();
virtual ~CDecoder();
};
}}

View File

@@ -0,0 +1,138 @@
// (C) 2016 Tino Reichardt
#include "StdAfx.h"
#include "Lz5Encoder.h"
#include "Lz5Decoder.h"
#ifndef EXTRACT_ONLY
namespace NCompress {
namespace NLZ5 {
CEncoder::CEncoder():
_processedIn(0),
_processedOut(0),
_inputSize(0),
_ctx(NULL),
_numThreads(NWindows::NSystem::GetNumberOfProcessors())
{
_props.clear();
}
CEncoder::~CEncoder()
{
if (_ctx)
LZ5MT_freeCCtx(_ctx);
}
STDMETHODIMP CEncoder::SetCoderProperties(const PROPID * propIDs, const PROPVARIANT * coderProps, UInt32 numProps)
{
_props.clear();
for (UInt32 i = 0; i < numProps; i++)
{
const PROPVARIANT & prop = coderProps[i];
PROPID propID = propIDs[i];
UInt32 v = (UInt32)prop.ulVal;
switch (propID)
{
case NCoderPropID::kLevel:
{
if (prop.vt != VT_UI4)
return E_INVALIDARG;
_props._level = static_cast < Byte > (prop.ulVal);
Byte lz5_level = static_cast < Byte > (LZ5MT_LEVEL_MAX);
if (_props._level > lz5_level)
_props._level = lz5_level;
break;
}
case NCoderPropID::kNumThreads:
{
SetNumberOfThreads(v);
break;
}
default:
{
break;
}
}
}
return S_OK;
}
STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream * outStream)
{
return WriteStream(outStream, &_props, sizeof (_props));
}
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UInt64 * /*inSize*/ ,
const UInt64 * /*outSize */, ICompressProgressInfo *progress)
{
LZ5MT_RdWr_t rdwr;
size_t result;
HRESULT res = S_OK;
struct Lz5Stream Rd;
Rd.inStream = inStream;
Rd.outStream = outStream;
Rd.processedIn = &_processedIn;
Rd.processedOut = &_processedOut;
struct Lz5Stream Wr;
if (_processedIn == 0)
Wr.progress = progress;
else
Wr.progress = 0;
Wr.inStream = inStream;
Wr.outStream = outStream;
Wr.processedIn = &_processedIn;
Wr.processedOut = &_processedOut;
/* 1) setup read/write functions */
rdwr.fn_read = ::Lz5Read;
rdwr.fn_write = ::Lz5Write;
rdwr.arg_read = (void *)&Rd;
rdwr.arg_write = (void *)&Wr;
/* 2) create compression context, if needed */
if (!_ctx)
_ctx = LZ5MT_createCCtx(_numThreads, _props._level, _inputSize);
if (!_ctx)
return S_FALSE;
/* 3) compress */
result = LZ5MT_CompressCCtx(_ctx, &rdwr);
if (result == (size_t)-LZ5MT_error_read_fail)
res = E_ABORT;
if (LZ5MT_isError(result))
return ErrorOut(result);
return res;
}
STDMETHODIMP CEncoder::SetNumberOfThreads(UInt32 numThreads)
{
const UInt32 kNumThreadsMax = LZ5MT_THREAD_MAX;
if (numThreads < 1) numThreads = 1;
if (numThreads > kNumThreadsMax) numThreads = kNumThreadsMax;
_numThreads = numThreads;
return S_OK;
}
HRESULT CEncoder::ErrorOut(size_t code)
{
const char *strError = LZ5MT_getErrorString(code);
wchar_t wstrError[200+5]; /* no malloc here, /TR */
mbstowcs(wstrError, strError, 200);
MessageBoxW(0, wstrError, L"7-Zip ZStandard", MB_ICONERROR | MB_OK);
MyFree(wstrError);
return S_FALSE;
}
}}
#endif

View File

@@ -0,0 +1,63 @@
// (C) 2016 Tino Reichardt
#define LZ5_STATIC_LINKING_ONLY
#include "../../../C/Alloc.h"
#include "../../../C/Threads.h"
#include "../../../C/lz5/lz5.h"
#include "../../../C/zstdmt/lz5mt.h"
#include "../../Common/Common.h"
#include "../../Common/MyCom.h"
#include "../ICoder.h"
#include "../Common/StreamUtils.h"
#ifndef EXTRACT_ONLY
namespace NCompress {
namespace NLZ5 {
struct CProps
{
CProps() { clear (); }
void clear ()
{
memset(this, 0, sizeof (*this));
_ver_major = LZ5_VERSION_MAJOR;
_ver_minor = LZ5_VERSION_MINOR;
_level = 3;
}
Byte _ver_major;
Byte _ver_minor;
Byte _level;
Byte _reserved[2];
};
class CEncoder:
public ICompressCoder,
public ICompressSetCoderProperties,
public ICompressWriteCoderProperties,
public CMyUnknownImp
{
CProps _props;
UInt64 _processedIn;
UInt64 _processedOut;
UInt32 _inputSize;
UInt32 _numThreads;
LZ5MT_CCtx *_ctx;
HRESULT CEncoder::ErrorOut(size_t code);
public:
MY_UNKNOWN_IMP2 (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);
STDMETHODIMP CEncoder::SetNumberOfThreads(UInt32 numThreads);
CEncoder();
virtual ~CEncoder();
};
}}
#endif

View File

@@ -0,0 +1,17 @@
// (C) 2016 Tino Reichardt
#include "StdAfx.h"
#include "../Common/RegisterCodec.h"
#include "Lz5Decoder.h"
#ifndef EXTRACT_ONLY
#include "Lz5Encoder.h"
#endif
REGISTER_CODEC_E(
LZ5,
NCompress::NLZ5::CDecoder(),
NCompress::NLZ5::CEncoder(),
0x4F71105, "LZ5")

View File

@@ -1,33 +1,76 @@
// ZstdDecoder.cpp
// (C) 2016 Tino Reichardt
#include "StdAfx.h"
#include "ZstdDecoder.h"
int ZstdRead(void *arg, ZSTDMT_Buffer * in)
{
struct ZstdStream *x = (struct ZstdStream*)arg;
size_t size = in->size;
HRESULT res = ReadStream(x->inStream, in->buf, &size);
if (res != S_OK)
return -1;
in->size = size;
*x->processedIn += size;
return 0;
}
int ZstdWrite(void *arg, ZSTDMT_Buffer * out)
{
struct ZstdStream *x = (struct ZstdStream*)arg;
UInt32 todo = (UInt32)out->size;
UInt32 done = 0;
while (todo != 0)
{
UInt32 block;
HRESULT res = x->outStream->Write((char*)out->buf + done, todo, &block);
done += block;
if (res == k_My_HRESULT_WritingWasCut)
break;
if (res != S_OK)
return -1;
if (block == 0)
return E_FAIL;
todo -= block;
}
*x->processedOut += done;
if (x->progress)
x->progress->SetRatioInfo(x->processedIn, x->processedOut);
return 0;
}
namespace NCompress {
namespace NZSTD {
CDecoder::CDecoder():
_dstream(NULL),
_buffIn(NULL),
_buffOut(NULL),
_buffInSizeAllocated(0),
_buffOutSizeAllocated(0),
_buffInSize(ZSTD_DStreamInSize()),
_buffOutSize(ZSTD_DStreamOutSize()*4),
_processedIn(0),
_processedOut(0)
_processedOut(0),
_inputSize(0),
_numThreads(NWindows::NSystem::GetNumberOfProcessors())
{
_props.clear();
}
CDecoder::~CDecoder()
{
if (_dstream)
ZSTD_freeDStream(_dstream);
}
MyFree(_buffIn);
MyFree(_buffOut);
HRESULT CDecoder::ErrorOut(size_t code)
{
const char *strError = ZSTDMT_getErrorString(code);
wchar_t wstrError[200+5]; /* no malloc here, /TR */
mbstowcs(wstrError, strError, 200);
MessageBoxW(0, wstrError, L"7-Zip ZStandard", MB_ICONERROR | MB_OK);
MyFree(wstrError);
return S_FALSE;
}
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte * prop, UInt32 size)
@@ -37,97 +80,23 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte * prop, UInt32 size)
if (size != sizeof(DProps))
return E_FAIL;
#ifdef ZSTD_LEGACY_SUPPORT
/* version 0.x and 1.x are okay */
if (pProps->_ver_major > 1)
return E_FAIL;
/* 0.5, 0.6, 0.7, 0.8 are supported! */
if (pProps->_ver_major == 0) {
switch (pProps->_ver_minor) {
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
default:
return E_FAIL;
}}
#else
/* only exact version is okay */
if (pProps->_ver_major != ZSTD_VERSION_MAJOR)
return E_FAIL;
if (pProps->_ver_minor != ZSTD_VERSION_MINOR)
return E_FAIL;
#endif
memcpy(&_props, pProps, sizeof (DProps));
return S_OK;
}
HRESULT CDecoder::ErrorOut(size_t code)
STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads)
{
const char *strError = ZSTD_getErrorName(code);
size_t strErrorLen = strlen(strError) + 1;
wchar_t *wstrError = (wchar_t *)MyAlloc(sizeof(wchar_t) * strErrorLen);
if (!wstrError)
return E_FAIL;
mbstowcs(wstrError, strError, strErrorLen - 1);
MessageBoxW(0, wstrError, L"7-Zip ZStandard", MB_ICONERROR | MB_OK);
MyFree(wstrError);
return E_FAIL;
}
HRESULT CDecoder::CreateDecompressor()
{
size_t result;
if (!_dstream) {
_dstream = ZSTD_createDStream();
if (!_dstream)
return E_FAIL;
}
result = ZSTD_initDStream(_dstream);
if (ZSTD_isError(result))
return ErrorOut(result);
/* allocate buffers */
if (_buffInSizeAllocated != _buffInSize)
{
MyFree(_buffIn);
_buffIn = MyAlloc(_buffInSize);
if (!_buffIn)
return E_OUTOFMEMORY;
_buffInSizeAllocated = _buffInSize;
}
if (_buffOutSizeAllocated != _buffOutSize)
{
MyFree(_buffOut);
_buffOut = MyAlloc(_buffOutSize);
if (!_buffOut)
return E_OUTOFMEMORY;
_buffOutSizeAllocated = _buffOutSize;
}
const UInt32 kNumThreadsMax = ZSTDMT_THREAD_MAX;
if (numThreads < 1) numThreads = 1;
if (numThreads > kNumThreadsMax) numThreads = kNumThreadsMax;
_numThreads = numThreads;
return S_OK;
}
HRESULT CDecoder::SetOutStreamSizeResume(const UInt64 * /*outSize*/)
{
_processedOut = 0;
RINOK(CreateDecompressor());
return S_OK;
}
@@ -135,73 +104,48 @@ STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 * outSize)
{
_processedIn = 0;
RINOK(SetOutStreamSizeResume(outSize));
return S_OK;
}
STDMETHODIMP CDecoder::SetInBufSize(UInt32, UInt32 size)
HRESULT CDecoder::CodeSpec(ISequentialInStream * inStream,
ISequentialOutStream * outStream, ICompressProgressInfo * progress)
{
_buffInSize = size;
return S_OK;
}
STDMETHODIMP CDecoder::SetOutBufSize(UInt32, UInt32 size)
{
_buffOutSize = size;
return S_OK;
}
HRESULT CDecoder::CodeSpec(ISequentialInStream * inStream, ISequentialOutStream * outStream, ICompressProgressInfo * progress)
{
RINOK(CreateDecompressor());
ZSTDMT_RdWr_t rdwr;
size_t result;
UInt32 const toRead = static_cast < const UInt32 > (_buffInSize);
for(;;) {
UInt32 read;
HRESULT res = S_OK;
/* read input */
RINOK(inStream->Read(_buffIn, toRead, &read));
size_t InSize = static_cast < size_t > (read);
_processedIn += InSize;
struct ZstdStream Rd;
Rd.inStream = inStream;
Rd.processedIn = &_processedIn;
if (InSize == 0)
return S_OK;
struct ZstdStream Wr;
Wr.progress = progress;
Wr.outStream = outStream;
Wr.processedIn = &_processedIn;
Wr.processedOut = &_processedOut;
/* decompress input */
ZSTD_inBuffer input = { _buffIn, InSize, 0 };
for (;;) {
ZSTD_outBuffer output = { _buffOut, _buffOutSize, 0 };
result = ZSTD_decompressStream(_dstream, &output , &input);
#if 0
printf("%s in=%d out=%d result=%d in.pos=%d in.size=%d\n", __FUNCTION__,
InSize, output.pos, result, input.pos, input.size);
fflush(stdout);
#endif
if (ZSTD_isError(result))
return ErrorOut(result);
/* 1) setup read/write functions */
rdwr.fn_read = ::ZstdRead;
rdwr.fn_write = ::ZstdWrite;
rdwr.arg_read = (void *)&Rd;
rdwr.arg_write = (void *)&Wr;
/* write decompressed stream and update progress */
RINOK(WriteStream(outStream, _buffOut, output.pos));
_processedOut += output.pos;
RINOK(progress->SetRatioInfo(&_processedIn, &_processedOut));
/* 2) create decompression context */
ZSTDMT_DCtx *ctx = ZSTDMT_createDCtx(_numThreads, _inputSize);
if (!ctx)
return S_FALSE;
/* one more round */
if ((input.pos == input.size) && (result == 1) && output.pos)
continue;
/* 3) decompress */
result = ZSTDMT_decompressDCtx(ctx, &rdwr);
//printf("decompress = %d / %d\n", result, ZSTDMT_error_read_fail);
if (result == (size_t)-ZSTDMT_error_read_fail)
res = E_ABORT;
else if (ZSTDMT_isError(result))
return ErrorOut(result);
/* finished */
if (input.pos == input.size)
break;
/* end of frame */
if (result == 0) {
result = ZSTD_initDStream(_dstream);
if (ZSTD_isError(result))
return ErrorOut(result);
}
}
}
/* 4) free resources */
ZSTDMT_freeDCtx(ctx);
return res;
}
STDMETHODIMP CDecoder::Code(ISequentialInStream * inStream, ISequentialOutStream * outStream,
@@ -221,69 +165,14 @@ STDMETHODIMP CDecoder::SetInStream(ISequentialInStream * inStream)
STDMETHODIMP CDecoder::ReleaseInStream()
{
_inStream.Release();
return S_OK;
}
STDMETHODIMP CDecoder::Read(void *data, UInt32 /*size*/, UInt32 *processedSize)
{
if (processedSize)
*processedSize = 0;
size_t result;
if (!_dstream)
if (CreateDecompressor() != S_OK)
return E_FAIL;
UInt32 read, toRead = static_cast < UInt32 > (_buffInSize);
Byte *dataout = static_cast < Byte* > (data);
for(;;) {
/* read input */
RINOK(_inStream->Read(_buffIn, toRead, &read));
size_t InSize = static_cast < size_t > (read);
_processedIn += InSize;
if (InSize == 0) {
return S_OK;
}
/* decompress input */
ZSTD_inBuffer input = { _buffIn, InSize, 0 };
for (;;) {
ZSTD_outBuffer output = { dataout, _buffOutSize, 0 };
result = ZSTD_decompressStream(_dstream, &output , &input);
if (ZSTD_isError(result))
return ErrorOut(result);
if (processedSize)
*processedSize += static_cast < UInt32 > (output.pos);
dataout += output.pos;
/* one more round */
if ((input.pos == input.size) && (result == 1) && output.pos)
continue;
/* finished */
if (input.pos == input.size)
break;
/* end of frame */
if (result == 0) {
result = ZSTD_initDStream(_dstream);
if (ZSTD_isError(result))
return ErrorOut(result);
}
}
}
}
#endif
HRESULT CDecoder::CodeResume(ISequentialOutStream * outStream, const UInt64 * outSize, ICompressProgressInfo * progress)
{
RINOK(SetOutStreamSizeResume(outSize));
return CodeSpec(_inStream, outStream, progress);
}
#endif
}}

View File

@@ -1,22 +1,36 @@
// ZstdDecoder.h
// (C) 2016 Tino Reichardt
/**
* you can define ZSTD_LEGACY_SUPPORT to be backwards compatible
* with these versions: 0.5, 0.6, 0.7, 0.8 (0.8 == 1.0)
*
* /TR 2016-09-04
* you can define ZSTD_LEGACY_SUPPORT to be backwards compatible (0.1 .. 0.7)
* /TR 2016-10-01
*/
#define ZSTD_STATIC_LINKING_ONLY
#include "../../../C/Alloc.h"
#include "../../../C/ZStd/zstd.h"
#include "../../../C/Threads.h"
#include "../../../C/zstd/zstd.h"
#include "../../../C/zstdmt/zstdmt.h"
#include "../../Windows/System.h"
#include "../../Common/Common.h"
#include "../../Common/MyCom.h"
#include "../ICoder.h"
#include "../Common/StreamUtils.h"
#include "../Common/RegisterCodec.h"
#include "../Common/ProgressMt.h"
struct ZstdStream {
ISequentialInStream *inStream;
ISequentialOutStream *outStream;
ICompressProgressInfo *progress;
UInt64 *processedIn;
UInt64 *processedOut;
CCriticalSection *cs;
int flags;
};
extern int ZstdRead(void *Stream, ZSTDMT_Buffer * in);
extern int ZstdWrite(void *Stream, ZSTDMT_Buffer * in);
namespace NCompress {
namespace NZSTD {
@@ -39,60 +53,44 @@ struct DProps
};
class CDecoder:public ICompressCoder,
public ICompressSetDecoderProperties2, public ICompressSetBufSize,
#ifndef NO_READ_FROM_CODER
public ICompressSetInStream,
public ICompressSetOutStreamSize, public ISequentialInStream,
#endif
public ICompressSetDecoderProperties2,
public CMyUnknownImp
{
CMyComPtr < ISequentialInStream > _inStream;
DProps _props;
ZSTD_DStream *_dstream;
void *_buffIn;
void *_buffOut;
size_t _buffInSize;
size_t _buffOutSize;
size_t _buffInSizeAllocated;
size_t _buffOutSizeAllocated;
CCriticalSection cs;
UInt64 _processedIn;
UInt64 _processedOut;
UInt32 _inputSize;
UInt32 _numThreads;
HRESULT CDecoder::CreateDecompressor();
HRESULT CDecoder::ErrorOut(size_t code);
HRESULT CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress);
HRESULT SetOutStreamSizeResume(const UInt64 *outSize);
public:
MY_QUERYINTERFACE_BEGIN2 (ICompressCoder)
MY_QUERYINTERFACE_ENTRY (ICompressSetDecoderProperties2)
MY_QUERYINTERFACE_ENTRY (ICompressSetBufSize)
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2)
#ifndef NO_READ_FROM_CODER
MY_QUERYINTERFACE_ENTRY (ICompressSetInStream)
MY_QUERYINTERFACE_ENTRY (ICompressSetOutStreamSize)
MY_QUERYINTERFACE_ENTRY (ISequentialInStream)
MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
#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 (SetOutStreamSize) (const UInt64 *outSize);
STDMETHOD (SetInBufSize) (UInt32 streamIndex, UInt32 size);
STDMETHOD (SetOutBufSize) (UInt32 streamIndex, UInt32 size);
STDMETHOD (SetDecoderProperties2)(const Byte *data, UInt32 size);
STDMETHOD (SetOutStreamSize)(const UInt64 *outSize);
STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads);
#ifndef NO_READ_FROM_CODER
STDMETHOD (SetInStream) (ISequentialInStream *inStream);
STDMETHOD (ReleaseInStream) ();
STDMETHOD (Read) (void *data, UInt32 size, UInt32 *processedSize);
HRESULT CodeResume (ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress);
UInt64 GetInputProcessedSize () const { return _processedIn; }
STDMETHOD (SetInStream)(ISequentialInStream *inStream);
STDMETHOD (ReleaseInStream)();
UInt64 GetInputProcessedSize() const { return _processedIn; }
#endif
HRESULT CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress);
CDecoder();
virtual ~CDecoder();

View File

@@ -1,32 +1,27 @@
// ZstdEncoder.cpp
// (C) 2016 Tino Reichardt
#include "StdAfx.h"
#include "ZstdEncoder.h"
#include "ZstdDecoder.h"
#ifndef EXTRACT_ONLY
namespace NCompress {
namespace NZSTD {
CEncoder::CEncoder():
_cstream(NULL),
_buffIn(NULL),
_buffOut(NULL),
_buffInSize(0),
_buffOutSize(0),
_processedIn(0),
_processedOut(0)
_processedOut(0),
_inputSize(0),
_ctx(NULL),
_numThreads(NWindows::NSystem::GetNumberOfProcessors())
{
_props.clear();
}
CEncoder::~CEncoder()
{
if (_cstream)
ZSTD_freeCStream(_cstream);
MyFree(_buffIn);
MyFree(_buffOut);
if (_ctx)
ZSTDMT_freeCCtx(_ctx);
}
STDMETHODIMP CEncoder::SetCoderProperties(const PROPID * propIDs, const PROPVARIANT * coderProps, UInt32 numProps)
@@ -37,6 +32,7 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID * propIDs, const PROPVARI
{
const PROPVARIANT & prop = coderProps[i];
PROPID propID = propIDs[i];
UInt32 v = (UInt32)prop.ulVal;
switch (propID)
{
case NCoderPropID::kLevel:
@@ -52,6 +48,11 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID * propIDs, const PROPVARI
break;
}
case NCoderPropID::kNumThreads:
{
SetNumberOfThreads(v);
break;
}
default:
{
break;
@@ -59,9 +60,6 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID * propIDs, const PROPVARI
}
}
_processedIn = 0;
_processedOut = 0;
return S_OK;
}
@@ -71,75 +69,70 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream * outStream)
}
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UInt64 * /* inSize */ ,
const UInt64 * /* outSize */ , ICompressProgressInfo *progress)
ISequentialOutStream *outStream, const UInt64 * /*inSize*/ ,
const UInt64 * /*outSize */, ICompressProgressInfo *progress)
{
ZSTDMT_RdWr_t rdwr;
size_t result;
HRESULT res = S_OK;
/* init only once in beginning */
if (!_cstream) {
struct ZstdStream Rd;
Rd.inStream = inStream;
Rd.outStream = outStream;
Rd.processedIn = &_processedIn;
Rd.processedOut = &_processedOut;
/* allocate stream */
_cstream = ZSTD_createCStream();
if (!_cstream)
return E_OUTOFMEMORY;
struct ZstdStream Wr;
if (_processedIn == 0)
Wr.progress = progress;
else
Wr.progress = 0;
Wr.inStream = inStream;
Wr.outStream = outStream;
Wr.processedIn = &_processedIn;
Wr.processedOut = &_processedOut;
/* allocate buffers */
_buffInSize = ZSTD_CStreamInSize();
_buffIn = MyAlloc(_buffInSize);
if (!_buffIn)
return E_OUTOFMEMORY;
/* 1) setup read/write functions */
rdwr.fn_read = ::ZstdRead;
rdwr.fn_write = ::ZstdWrite;
rdwr.arg_read = (void *)&Rd;
rdwr.arg_write = (void *)&Wr;
_buffOutSize = ZSTD_CStreamOutSize();
_buffOut = MyAlloc(_buffOutSize);
if (!_buffOut)
return E_OUTOFMEMORY;
}
/* init or re-init stream */
result = ZSTD_initCStream(_cstream, _props._level);
if (ZSTD_isError(result))
/* 2) create compression context, if needed */
if (!_ctx)
_ctx = ZSTDMT_createCCtx(_numThreads, _props._level, _inputSize);
if (!_ctx)
return S_FALSE;
UInt32 read, toRead = static_cast < UInt32 > (_buffInSize);
for(;;) {
/* 3) compress */
result = ZSTDMT_compressCCtx(_ctx, &rdwr);
if (result == (size_t)-ZSTDMT_error_read_fail)
res = E_ABORT;
else if (ZSTDMT_isError(result))
return ErrorOut(result);
/* read input */
RINOK(inStream->Read(_buffIn, toRead, &read));
size_t InSize = static_cast < size_t > (read);
_processedIn += InSize;
return res;
}
if (InSize == 0) {
STDMETHODIMP CEncoder::SetNumberOfThreads(UInt32 numThreads)
{
const UInt32 kNumThreadsMax = ZSTDMT_THREAD_MAX;
if (numThreads < 1) numThreads = 1;
if (numThreads > kNumThreadsMax) numThreads = kNumThreadsMax;
_numThreads = numThreads;
return S_OK;
}
/* @eof */
ZSTD_outBuffer output = { _buffOut, _buffOutSize, 0 };
result = ZSTD_endStream(_cstream, &output);
if (ZSTD_isError(result))
return S_FALSE;
HRESULT CEncoder::ErrorOut(size_t code)
{
const char *strError = ZSTDMT_getErrorString(code);
wchar_t wstrError[200+5]; /* no malloc here, /TR */
if (output.pos) {
/* write last compressed bytes and update progress */
RINOK(WriteStream(outStream, _buffOut, output.pos));
_processedOut += output.pos;
RINOK(progress->SetRatioInfo(&_processedIn, &_processedOut));
}
mbstowcs(wstrError, strError, 200);
MessageBoxW(0, wstrError, L"7-Zip ZStandard", MB_ICONERROR | MB_OK);
MyFree(wstrError);
return S_OK;
}
/* compress input */
ZSTD_inBuffer input = { _buffIn, InSize, 0 };
while (input.pos < input.size) {
ZSTD_outBuffer output = { _buffOut, _buffOutSize, 0 };
result = ZSTD_compressStream(_cstream, &output , &input);
if (ZSTD_isError(result))
return S_FALSE;
/* write compressed stream and update progress */
RINOK(WriteStream(outStream, _buffOut, output.pos));
_processedOut += output.pos;
RINOK(progress->SetRatioInfo(&_processedIn, &_processedOut));
}
}
return S_FALSE;
}
}}

View File

@@ -1,9 +1,10 @@
// ZstdEncoder.h
// (C) 2016 Tino Reichardt
#define ZSTD_STATIC_LINKING_ONLY
#include "../../../C/Alloc.h"
#include "../../../C/ZStd/zstd.h"
#include "../../../C/Threads.h"
#include "../../../C/zstd/zstd.h"
#include "../../../C/zstdmt/zstdmt.h"
#include "../../Common/Common.h"
#include "../../Common/MyCom.h"
@@ -39,21 +40,20 @@ class CEncoder:
{
CProps _props;
ZSTD_CStream *_cstream;
void *_buffIn;
void *_buffOut;
size_t _buffInSize;
size_t _buffOutSize;
UInt64 _processedIn;
UInt64 _processedOut;
UInt32 _inputSize;
UInt32 _numThreads;
HRESULT CreateCompressor();
ZSTDMT_CCtx *_ctx;
HRESULT CEncoder::ErrorOut(size_t code);
public:
MY_UNKNOWN_IMP2 (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);
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);
STDMETHODIMP CEncoder::SetNumberOfThreads(UInt32 numThreads);
CEncoder();
virtual ~CEncoder();

View File

@@ -1,4 +1,3 @@
// ZstdRegister.cpp
// (C) 2016 Tino Reichardt
#include "StdAfx.h"

View File

@@ -161,8 +161,11 @@ Handler GUIDs:
0A lzma
0B lzma86
0C xz
0D ppmd
0E zstd
0F lz4
10 lz5
C6 Lzip
C7 Ext
C8 VMDK
C9 VDI

View File

@@ -1066,6 +1066,7 @@ static const char * const k_Formats_with_simple_signuature[] =
, "rar"
, "bzip2"
, "gzip"
, "lzip"
, "cab"
, "wim"
, "rpm"

View File

@@ -283,8 +283,12 @@ static const char * const kArcExts[] =
"7z"
, "bz2"
, "gz"
, "lz"
, "lz4"
, "lz5"
, "rar"
, "zip"
, "zst"
};
static bool IsItArcExt(const UString &ext)

View File

@@ -46,7 +46,7 @@ static const UInt32 kLangIDs[] =
IDT_COMPRESS_SOLID,
IDT_COMPRESS_THREADS,
IDT_COMPRESS_PARAMETERS,
IDG_COMPRESS_OPTIONS,
IDX_COMPRESS_SFX,
IDX_COMPRESS_SHARED,
@@ -87,13 +87,9 @@ static const UInt32 g_Levels[] =
{
IDS_METHOD_STORE,
IDS_METHOD_FASTEST,
0,
IDS_METHOD_FAST,
0,
IDS_METHOD_NORMAL,
0,
IDS_METHOD_MAXIMUM,
0,
IDS_METHOD_ULTRA
};
@@ -101,6 +97,8 @@ enum EMethodID
{
kCopy,
kZSTD,
kLZ4,
kLZ5,
kLZMA,
kLZMA2,
kPPMd,
@@ -114,6 +112,8 @@ static const LPCWSTR kMethodsNames[] =
{
L"Copy",
L"ZSTD",
L"LZ4",
L"LZ5",
L"LZMA",
L"LZMA2",
L"PPMd",
@@ -126,6 +126,8 @@ static const LPCWSTR kMethodsNames[] =
static const EMethodID g_7zMethods[] =
{
kZSTD,
kLZ4,
kLZ5,
kLZMA2,
kLZMA,
kPPMd,
@@ -167,6 +169,21 @@ static const EMethodID g_XzMethods[] =
kLZMA2
};
static const EMethodID g_ZstdMethods[] =
{
kZSTD
};
static const EMethodID g_Lz4Methods[] =
{
kLZ4
};
static const EMethodID g_Lz5Methods[] =
{
kLZ5
};
static const EMethodID g_SwfcMethods[] =
{
kDeflate
@@ -227,6 +244,24 @@ static const CFormatInfo g_Formats[] =
METHODS_PAIR(g_XzMethods),
false, false, true, false, false, false
},
{
L"zstd",
(1 << 0) | (1 << 1) | (1 << 5) | (1 << 11) | (1 << 17) | (1 << 22),
METHODS_PAIR(g_ZstdMethods),
false, false, true, false, false, false
},
{
L"lz4",
(1 << 0) | (1 << 1) | (1 << 3) | (1 << 7) | (1 << 11) | (1 << 16),
METHODS_PAIR(g_Lz4Methods),
false, false, true, false, false, false
},
{
L"lz5",
(1 << 0) | (1 << 1) | (1 << 3) | (1 << 7) | (1 << 11) | (1 << 16),
METHODS_PAIR(g_Lz5Methods),
false, false, true, false, false, false
},
{
L"Swfc",
(1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
@@ -281,7 +316,7 @@ static const
NCompressDialog::NUpdateMode::kFresh,
NCompressDialog::NUpdateMode::kSync
};
static const UInt32 k_UpdateMode_IDs[] =
{
IDS_COMPRESS_UPDATE_MODE_ADD,
@@ -324,7 +359,7 @@ void CCompressDialog::GetButton_Bools(UINT id, CBoolPair &b1, CBoolPair &b2)
b1.Val = b2.Val = val;
}
bool CCompressDialog::OnInit()
{
#ifdef LANG
@@ -346,7 +381,7 @@ bool CCompressDialog::OnInit()
m_Order.Attach(GetItem(IDC_COMPRESS_ORDER));
m_Solid.Attach(GetItem(IDC_COMPRESS_SOLID));
m_NumThreads.Attach(GetItem(IDC_COMPRESS_THREADS));
m_UpdateMode.Attach(GetItem(IDC_COMPRESS_UPDATE_MODE));
m_PathMode.Attach(GetItem(IDC_COMPRESS_PATH_MODE));
@@ -358,7 +393,7 @@ bool CCompressDialog::OnInit()
m_RegistryInfo.Load();
CheckButton(IDX_PASSWORD_SHOW, m_RegistryInfo.ShowPassword);
CheckButton(IDX_COMPRESS_ENCRYPT_FILE_NAMES, m_RegistryInfo.EncryptHeaders);
CheckButton_TwoBools(IDX_COMPRESS_NT_SYM_LINKS, Info.SymLinks, m_RegistryInfo.SymLinks);
CheckButton_TwoBools(IDX_COMPRESS_NT_HARD_LINKS, Info.HardLinks, m_RegistryInfo.HardLinks);
CheckButton_TwoBools(IDX_COMPRESS_NT_ALT_STREAMS, Info.AltStreams, m_RegistryInfo.AltStreams);
@@ -396,7 +431,7 @@ bool CCompressDialog::OnInit()
}
SetLevel();
SetParams();
for (unsigned i = 0; i < m_RegistryInfo.ArcPaths.Size() && i < kHistorySize; i++)
m_ArchivePath.AddString(m_RegistryInfo.ArcPaths[i]);
@@ -517,7 +552,7 @@ void CCompressDialog::CheckControlsEnable()
bool multiThreadEnable = fi.MultiThread;
Info.MultiThreadIsAllowed = multiThreadEnable;
Info.EncryptHeadersIsAllowed = fi.EncryptFileNames;
EnableItem(IDC_COMPRESS_SOLID, fi.Solid);
EnableItem(IDC_COMPRESS_THREADS, multiThreadEnable);
@@ -525,7 +560,7 @@ void CCompressDialog::CheckControlsEnable()
{
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
ShowItem_Bool(IDX_COMPRESS_NT_SYM_LINKS, ai.Flags_SymLinks());
ShowItem_Bool(IDX_COMPRESS_NT_HARD_LINKS, ai.Flags_HardLinks());
ShowItem_Bool(IDX_COMPRESS_NT_ALT_STREAMS, ai.Flags_AltStreams());
@@ -725,12 +760,12 @@ void CCompressDialog::OnOK()
ShowErrorMessage(*this, k_IncorrectPathMessage);
return;
}
m_RegistryInfo.ArcPaths.Clear();
AddUniqueString(m_RegistryInfo.ArcPaths, s);
Info.ArcPath = s;
}
Info.UpdateMode = (NCompressDialog::NUpdateMode::EEnum)k_UpdateMode_Vals[m_UpdateMode.GetCurSel()];;
Info.PathMode = (NWildcard::ECensorPathMode)k_PathMode_Vals[m_PathMode.GetCurSel()];
@@ -770,12 +805,12 @@ void CCompressDialog::OnOK()
}
m_Params.GetText(Info.Options);
UString volumeString;
m_Volume.GetText(volumeString);
volumeString.Trim();
Info.VolumeSizes.Clear();
if (!volumeString.IsEmpty())
{
if (!ParseVolumeSizes(volumeString, Info.VolumeSizes))
@@ -804,16 +839,16 @@ void CCompressDialog::OnOK()
sTemp.Trim();
AddUniqueString(m_RegistryInfo.ArcPaths, sTemp);
}
if (m_RegistryInfo.ArcPaths.Size() > kHistorySize)
m_RegistryInfo.ArcPaths.DeleteBack();
if (Info.FormatIndex >= 0)
m_RegistryInfo.ArcType = (*ArcFormats)[Info.FormatIndex].Name;
m_RegistryInfo.ShowPassword = IsShowPasswordChecked();
m_RegistryInfo.Save();
CModalDialog::OnOK();
}
@@ -867,10 +902,6 @@ bool CCompressDialog::OnCommand(int code, int itemID, LPARAM lParam)
}
case IDC_COMPRESS_LEVEL:
{
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
int index = FindRegistryFormatAlways(ai.Name);
NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
fo.ResetForLevelChange();
SetMethod(GetMethodID());
SetSolidBlockSize();
SetNumThreads();
@@ -880,13 +911,7 @@ bool CCompressDialog::OnCommand(int code, int itemID, LPARAM lParam)
}
case IDC_COMPRESS_METHOD:
{
// MessageBoxW(*this, L"IDC_COMPRESS_METHOD!", L"7-Zip", MB_ICONERROR);
if (GetMethodID() == kZSTD)
{
SetLevel_zstd();
} else {
SetLevel_default();
}
SetLevel();
SetDictionary();
SetOrder();
SetSolidBlockSize();
@@ -1018,10 +1043,13 @@ void CCompressDialog::SetNearestSelectComboBox(NControl::CComboBox &comboBox, UI
comboBox.SetCurSel(0);
}
void CCompressDialog::SetLevel_zstd()
void CCompressDialog::SetLevel()
{
UInt32 level = GetLevel2();
UInt32 LevelsMask;
UInt32 langID = 0;
SetMethod(GetMethodID());
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
{
int index = FindRegistryFormat(ai.Name);
@@ -1030,92 +1058,45 @@ void CCompressDialog::SetLevel_zstd()
const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
if (fo.Level <= 22)
level = fo.Level;
else
level = 5;
}
}
/* ZStandard has 22 levels */
m_Level.ResetContent();
if (GetMethodID() == kZSTD)
LevelsMask = g_Formats[6].LevelsMask;
else if (GetMethodID() == kLZ4)
LevelsMask = g_Formats[7].LevelsMask;
else if (GetMethodID() == kLZ5)
LevelsMask = g_Formats[8].LevelsMask;
else
LevelsMask = g_Formats[GetStaticFormatIndex()].LevelsMask;
for (unsigned i = 0; i <= 22; i++)
{
TCHAR s[40];
TCHAR t[50] = { TEXT('L'), TEXT('e'), TEXT('v'), TEXT('e'), TEXT('l'), TEXT(' '), 0 };
ConvertUInt32ToString(i, s);
lstrcat(t, s);
switch (i) {
case 0:
lstrcat(t, TEXT(" ("));
lstrcat(t, LangString(IDS_METHOD_STORE));
lstrcat(t, TEXT(")"));
break;
case 1:
lstrcat(t, TEXT(" ("));
lstrcat(t, LangString(IDS_METHOD_FASTEST));
lstrcat(t, TEXT(")"));
break;
case 5:
lstrcat(t, TEXT(" ("));
lstrcat(t, LangString(IDS_METHOD_FAST));
lstrcat(t, TEXT(")"));
break;
case 11:
lstrcat(t, TEXT(" ("));
lstrcat(t, LangString(IDS_METHOD_NORMAL));
lstrcat(t, TEXT(")"));
break;
case 17:
lstrcat(t, TEXT(" ("));
lstrcat(t, LangString(IDS_METHOD_MAXIMUM));
lstrcat(t, TEXT(")"));
break;
case 22:
lstrcat(t, TEXT(" ("));
lstrcat(t, LangString(IDS_METHOD_ULTRA));
lstrcat(t, TEXT(")"));
break;
}
int index = (int)m_Level.AddString(t);
m_Level.SetItemData(index, i);
}
SetNearestSelectComboBox(m_Level, level);
return;
}
// max reached
if (LevelsMask < (UInt32)(1 << i))
break;
void CCompressDialog::SetLevel_default()
{
UInt32 level = GetLevel2();
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
{
int index = FindRegistryFormat(ai.Name);
if (index >= 0)
if ((LevelsMask & (1 << i)) != 0)
{
const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
if (fo.Level <= 9)
level = fo.Level;
else
level = 9;
}
}
/* 9 default levels */
m_Level.ResetContent();
const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
for (unsigned i = 0; i <= 9; i++)
{
if ((fi.LevelsMask & (1 << i)) != 0)
{
TCHAR s[40];
TCHAR t[50] = { TEXT('L'), TEXT('e'), TEXT('v'), TEXT('e'), TEXT('l'), TEXT(' '), 0 };
UInt32 langID = g_Levels[i];
ConvertUInt32ToString(i, s);
lstrcat(t, s);
lstrcat(t, TEXT(" ("));
lstrcat(t, LangString(langID));
lstrcat(t, LangString(g_Levels[langID]));
lstrcat(t, TEXT(")"));
int index = (int)m_Level.AddString(t);
m_Level.SetItemData(index, i);
langID++;
} else {
ConvertUInt32ToString(i, s);
lstrcat(t, s);
int index = (int)m_Level.AddString(t);
m_Level.SetItemData(index, i);
}
}
@@ -1123,18 +1104,6 @@ void CCompressDialog::SetLevel_default()
return;
}
void CCompressDialog::SetLevel()
{
SetMethod();
if (GetMethodID() == kZSTD)
{
SetLevel_zstd();
} else {
SetLevel_default();
}
}
void CCompressDialog::SetMethod(int keepMethodId)
{
m_Method.ResetContent();
@@ -1156,7 +1125,7 @@ void CCompressDialog::SetMethod(int keepMethodId)
}
bool isSfx = IsSFX();
bool weUseSameMethod = false;
for (unsigned m = 0; m < fi.NumMethods; m++)
{
EMethodID methodID = fi.MethodIDs[m];
@@ -1266,21 +1235,21 @@ void CCompressDialog::SetDictionary()
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
int index = FindRegistryFormat(ai.Name);
UInt32 defaultDict = (UInt32)(Int32)-1;
if (index >= 0)
{
const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
if (fo.Method.IsEqualTo_NoCase(GetMethodSpec()))
defaultDict = fo.Dictionary;
}
int methodID = GetMethodID();
UInt32 level = GetLevel2();
if (methodID < 0)
return;
UInt64 maxRamSize;
bool maxRamSize_Defined = GetMaxRamSizeForProgram(maxRamSize);
switch (methodID)
{
case kLZMA:
@@ -1295,17 +1264,17 @@ void CCompressDialog::SetDictionary()
else if (level >= 3) defaultDict = (1 << 20);
else defaultDict = (kMinDicSize);
}
AddDictionarySize(kMinDicSize);
m_Dictionary.SetCurSel(0);
for (unsigned i = 20; i <= 31; i++)
for (unsigned j = 0; j < 2; j++)
{
if (i == 20 && j > 0)
continue;
UInt32 dict = ((UInt32)(2 + j) << (i - 1));
if (dict >
#ifdef MY_CPU_64BIT
(3 << 29)
@@ -1314,7 +1283,7 @@ void CCompressDialog::SetDictionary()
#endif
)
continue;
AddDictionarySize(dict);
UInt64 decomprSize;
UInt64 requiredComprSize = GetMemoryUsage(dict, decomprSize);
@@ -1325,7 +1294,7 @@ void CCompressDialog::SetDictionary()
// SetNearestSelectComboBox(m_Dictionary, defaultDict);
break;
}
case kPPMd:
{
if (defaultDict == (UInt32)(Int32)-1)
@@ -1357,7 +1326,7 @@ void CCompressDialog::SetDictionary()
|| m_Dictionary.GetCount() == 1)
m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1);
}
// SetNearestSelectComboBox(m_Dictionary, defaultDict);
break;
}
@@ -1368,14 +1337,14 @@ void CCompressDialog::SetDictionary()
m_Dictionary.SetCurSel(0);
break;
}
case kDeflate64:
{
AddDictionarySize(64 << 10);
m_Dictionary.SetCurSel(0);
break;
}
case kBZip2:
{
if (defaultDict == (UInt32)(Int32)-1)
@@ -1384,7 +1353,7 @@ void CCompressDialog::SetDictionary()
else if (level >= 3) defaultDict = (500 << 10);
else defaultDict = (100 << 10);
}
for (unsigned i = 1; i <= 9; i++)
{
UInt32 dict = ((UInt32)i * 100) << 10;
@@ -1392,15 +1361,15 @@ void CCompressDialog::SetDictionary()
if (dict <= defaultDict || m_Dictionary.GetCount() == 0)
m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1);
}
break;
}
case kPPMdZip:
{
if (defaultDict == (UInt32)(Int32)-1)
defaultDict = (1 << (19 + (level > 8 ? 8 : level)));
for (unsigned i = 20; i <= 28; i++)
{
UInt32 dict = (1 << i);
@@ -1411,7 +1380,7 @@ void CCompressDialog::SetDictionary()
|| m_Dictionary.GetCount() == 1)
m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1);
}
// SetNearestSelectComboBox(m_Dictionary, defaultDict);
break;
}
@@ -1449,7 +1418,7 @@ void CCompressDialog::SetOrder()
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
int index = FindRegistryFormat(ai.Name);
UInt32 defaultOrder = (UInt32)(Int32)-1;
if (index >= 0)
{
const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
@@ -1461,7 +1430,7 @@ void CCompressDialog::SetOrder()
UInt32 level = GetLevel2();
if (methodID < 0)
return;
switch (methodID)
{
case kLZMA:
@@ -1480,7 +1449,7 @@ void CCompressDialog::SetOrder()
SetNearestSelectComboBox(m_Order, defaultOrder);
break;
}
case kPPMd:
{
if (defaultOrder == (UInt32)(Int32)-1)
@@ -1490,10 +1459,10 @@ void CCompressDialog::SetOrder()
else if (level >= 5) defaultOrder = 6;
else defaultOrder = 4;
}
AddOrder(2);
AddOrder(3);
for (unsigned i = 2; i < 8; i++)
for (unsigned j = 0; j < 4; j++)
{
@@ -1501,12 +1470,12 @@ void CCompressDialog::SetOrder()
if (order < 32)
AddOrder(order);
}
AddOrder(32);
SetNearestSelectComboBox(m_Order, defaultOrder);
break;
}
case kDeflate:
case kDeflate64:
{
@@ -1516,7 +1485,7 @@ void CCompressDialog::SetOrder()
else if (level >= 7) defaultOrder = 64;
else defaultOrder = 32;
}
for (unsigned i = 3; i <= 8; i++)
for (unsigned j = 0; j < 2; j++)
{
@@ -1524,15 +1493,15 @@ void CCompressDialog::SetOrder()
if (order <= 256)
AddOrder(order);
}
AddOrder(methodID == kDeflate64 ? 257 : 258);
SetNearestSelectComboBox(m_Order, defaultOrder);
break;
}
case kBZip2:
break;
case kPPMdZip:
{
if (defaultOrder == (UInt32)(Int32)-1)
@@ -1592,9 +1561,9 @@ void CCompressDialog::SetSolidBlockSize()
m_Solid.SetItemData(index, (UInt32)kNoSolidBlockSize);
m_Solid.SetCurSel(0);
}
bool needSet = (defaultBlockSize == (UInt32)(Int32)-1);
for (unsigned i = 20; i <= 36; i++)
{
if (needSet && dict >= (((UInt64)1 << (i - 7))) && i <= 32)
@@ -1607,12 +1576,12 @@ void CCompressDialog::SetSolidBlockSize()
int index = (int)m_Solid.AddString(s);
m_Solid.SetItemData(index, (UInt32)i);
}
{
int index = (int)m_Solid.AddString(LangString(IDS_COMPRESS_SOLID));
m_Solid.SetItemData(index, kSolidBlockSize);
}
if (defaultBlockSize == (UInt32)(Int32)-1)
defaultBlockSize = kSolidBlockSize;
if (defaultBlockSize != kNoSolidBlockSize)
@@ -1645,6 +1614,9 @@ void CCompressDialog::SetNumThreads()
int methodID = GetMethodID();
switch (methodID)
{
case kLZ4: numAlgoThreadsMax = 128; break;
case kLZ5: numAlgoThreadsMax = 128; break;
case kZSTD: numAlgoThreadsMax = 128; break;
case kLZMA: numAlgoThreadsMax = 2; break;
case kLZMA2: numAlgoThreadsMax = 32; break;
case kBZip2: numAlgoThreadsMax = 32; break;
@@ -1676,7 +1648,7 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory)
if (fi.Filter && level >= 9)
size += (12 << 20) * 2 + (5 << 20);
UInt32 numThreads = GetNumThreads2();
if (IsZipFormat())
{
UInt32 numSubThreads = 1;
@@ -1686,9 +1658,9 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory)
if (numMainThreads > 1)
size += (UInt64)numMainThreads << 25;
}
int methidId = GetMethodID();
switch (methidId)
{
case kLZMA:
@@ -1716,9 +1688,9 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory)
size1 += (2 << 20) + (4 << 20);
numThreads1 = 2;
}
UInt32 numBlockThreads = numThreads / numThreads1;
if (methidId == kLZMA || numBlockThreads == 1)
size1 += (UInt64)dict * 3 / 2;
else
@@ -1734,45 +1706,13 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory)
decompressMemory = dict + (2 << 20);
return size;
}
case kPPMd:
{
decompressMemory = dict + (2 << 20);
return size + decompressMemory;
}
case kZSTD:
{
/* Code Snippet for CPP/7zip/UI/GUI/CompressDialog.cpp with blocklen=131075 */
size = 0;
switch (level) {
case 1: size = 824228; decompressMemory = 415024; return size;
case 2: size = 1282980; decompressMemory = 415024; return size;
case 3: size = 922532; decompressMemory = 415024; return size;
case 4: size = 1414052; decompressMemory = 415024; return size;
case 5: size = 1545124; decompressMemory = 415024; return size;
case 6: size = 1807268; decompressMemory = 415024; return size;
case 7: size = 1807268; decompressMemory = 415024; return size;
case 8: size = 1807268; decompressMemory = 415024; return size;
case 9: size = 1807268; decompressMemory = 415024; return size;
case 10: size = 1807268; decompressMemory = 415024; return size;
case 11: size = 2331556; decompressMemory = 415024; return size;
case 12: size = 2331556; decompressMemory = 415024; return size;
case 13: size = 3380132; decompressMemory = 415024; return size;
case 14: size = 3004832; decompressMemory = 415024; return size;
case 15: size = 3004832; decompressMemory = 415024; return size;
case 16: size = 4697834; decompressMemory = 415024; return size;
case 17: size = 4697834; decompressMemory = 415024; return size;
case 18: size = 4697834; decompressMemory = 415024; return size;
case 19: size = 4697834; decompressMemory = 415024; return size;
case 20: size = 4697834; decompressMemory = 415024; return size;
case 21: size = 4697834; decompressMemory = 415024; return size;
case 22: size = 4697834; decompressMemory = 415024; return size;
}
decompressMemory = 0;
return size;
}
case kDeflate:
case kDeflate64:
{
@@ -1785,21 +1725,21 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory)
decompressMemory = (2 << 20);
return size;
}
case kBZip2:
{
decompressMemory = (7 << 20);
UInt64 memForOneThread = (10 << 20);
return size + memForOneThread * numThreads;
}
case kPPMdZip:
{
decompressMemory = dict + (2 << 20);
return size + (UInt64)decompressMemory * numThreads;
}
}
return (UInt64)(Int64)-1;
}
@@ -1821,7 +1761,7 @@ void CCompressDialog::PrintMemUsage(UINT res, UInt64 value)
lstrcat(s, TEXT(" MB"));
SetItemText(res, s);
}
void CCompressDialog::SetMemoryUsage()
{
UInt64 decompressMem;

View File

@@ -130,8 +130,6 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
void SetNearestSelectComboBox(NWindows::NControl::CComboBox &comboBox, UInt32 value);
void SetLevel();
void SetLevel_zstd();
void SetLevel_default();
void SetMethod(int keepMethodId = -1);
int GetMethodID();

View File

@@ -1,13 +0,0 @@
COMPRESS_OBJS = $(COMPRESS_OBJS) \
$O\ZstdDecoder.obj \
$O\ZstdEncoder.obj \
$O\ZstdRegister.obj \
ZSTD_OBJS = \
$O\entropy_common.obj \
$O\fse_decompress.obj \
$O\huf_decompress.obj \
$O\zstd_common.obj \
$O\zstd_decompress.obj \
$O\xxhash.obj \