mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-10 02:07:07 -06:00
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:
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
BIN
CPP/7zip/Archive/Icons/lz4.ico
Normal file
BIN
CPP/7zip/Archive/Icons/lz4.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
BIN
CPP/7zip/Archive/Icons/lz5.ico
Normal file
BIN
CPP/7zip/Archive/Icons/lz5.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
366
CPP/7zip/Archive/Lz4Handler.cpp
Normal file
366
CPP/7zip/Archive/Lz4Handler.cpp
Normal 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)
|
||||
|
||||
}}
|
||||
366
CPP/7zip/Archive/Lz5Handler.cpp
Normal file
366
CPP/7zip/Archive/Lz5Handler.cpp
Normal 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)
|
||||
|
||||
}}
|
||||
460
CPP/7zip/Archive/LzHandler.cpp
Normal file
460
CPP/7zip/Archive/LzHandler.cpp
Normal 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)
|
||||
|
||||
}}
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
3
CPP/7zip/Bundles/Codec_lz4/StdAfx.cpp
Normal file
3
CPP/7zip/Bundles/Codec_lz4/StdAfx.cpp
Normal file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
8
CPP/7zip/Bundles/Codec_lz4/StdAfx.h
Normal file
8
CPP/7zip/Bundles/Codec_lz4/StdAfx.h
Normal file
@@ -0,0 +1,8 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/Common.h"
|
||||
|
||||
#endif
|
||||
36
CPP/7zip/Bundles/Codec_lz4/makefile
Normal file
36
CPP/7zip/Bundles/Codec_lz4/makefile
Normal 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"
|
||||
6
CPP/7zip/Bundles/Codec_lz4/resource.rc
Normal file
6
CPP/7zip/Bundles/Codec_lz4/resource.rc
Normal 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"
|
||||
3
CPP/7zip/Bundles/Codec_lz5/StdAfx.cpp
Normal file
3
CPP/7zip/Bundles/Codec_lz5/StdAfx.cpp
Normal file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
8
CPP/7zip/Bundles/Codec_lz5/StdAfx.h
Normal file
8
CPP/7zip/Bundles/Codec_lz5/StdAfx.h
Normal file
@@ -0,0 +1,8 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/Common.h"
|
||||
|
||||
#endif
|
||||
36
CPP/7zip/Bundles/Codec_lz5/makefile
Normal file
36
CPP/7zip/Bundles/Codec_lz5/makefile
Normal 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"
|
||||
6
CPP/7zip/Bundles/Codec_lz5/resource.rc
Normal file
6
CPP/7zip/Bundles/Codec_lz5/resource.rc
Normal 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"
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -106,6 +106,4 @@ C_OBJS = \
|
||||
$O\Threads.obj \
|
||||
|
||||
!include "../../Crc.mak"
|
||||
|
||||
!include "../../zstd.mak"
|
||||
!include "../../7zip.mak"
|
||||
|
||||
@@ -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"
|
||||
|
||||
177
CPP/7zip/Compress/Lz4Decoder.cpp
Normal file
177
CPP/7zip/Compress/Lz4Decoder.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}}
|
||||
99
CPP/7zip/Compress/Lz4Decoder.h
Normal file
99
CPP/7zip/Compress/Lz4Decoder.h
Normal 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();
|
||||
};
|
||||
|
||||
}}
|
||||
139
CPP/7zip/Compress/Lz4Encoder.cpp
Normal file
139
CPP/7zip/Compress/Lz4Encoder.cpp
Normal 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
|
||||
63
CPP/7zip/Compress/Lz4Encoder.h
Normal file
63
CPP/7zip/Compress/Lz4Encoder.h
Normal 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
|
||||
17
CPP/7zip/Compress/Lz4Register.cpp
Normal file
17
CPP/7zip/Compress/Lz4Register.cpp
Normal 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")
|
||||
178
CPP/7zip/Compress/Lz5Decoder.cpp
Normal file
178
CPP/7zip/Compress/Lz5Decoder.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}}
|
||||
99
CPP/7zip/Compress/Lz5Decoder.h
Normal file
99
CPP/7zip/Compress/Lz5Decoder.h
Normal 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();
|
||||
};
|
||||
|
||||
}}
|
||||
138
CPP/7zip/Compress/Lz5Encoder.cpp
Normal file
138
CPP/7zip/Compress/Lz5Encoder.cpp
Normal 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
|
||||
63
CPP/7zip/Compress/Lz5Encoder.h
Normal file
63
CPP/7zip/Compress/Lz5Encoder.h
Normal 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
|
||||
17
CPP/7zip/Compress/Lz5Register.cpp
Normal file
17
CPP/7zip/Compress/Lz5Register.cpp
Normal 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")
|
||||
@@ -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
|
||||
|
||||
}}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// ZstdRegister.cpp
|
||||
// (C) 2016 Tino Reichardt
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1066,6 +1066,7 @@ static const char * const k_Formats_with_simple_signuature[] =
|
||||
, "rar"
|
||||
, "bzip2"
|
||||
, "gzip"
|
||||
, "lzip"
|
||||
, "cab"
|
||||
, "wim"
|
||||
, "rpm"
|
||||
|
||||
@@ -283,8 +283,12 @@ static const char * const kArcExts[] =
|
||||
"7z"
|
||||
, "bz2"
|
||||
, "gz"
|
||||
, "lz"
|
||||
, "lz4"
|
||||
, "lz5"
|
||||
, "rar"
|
||||
, "zip"
|
||||
, "zst"
|
||||
};
|
||||
|
||||
static bool IsItArcExt(const UString &ext)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 \
|
||||
Reference in New Issue
Block a user