This commit is contained in:
Igor Pavlov
2017-08-29 20:49:43 +01:00
committed by Kornel
parent 2efa10565a
commit b5dc853b24
110 changed files with 4714 additions and 1700 deletions

View File

@@ -21,18 +21,19 @@ namespace NLzma2 {
CEncoder::CEncoder()
{
_encoder = 0;
_encoder = NULL;
_encoder = Lzma2Enc_Create(&g_Alloc, &g_BigAlloc);
if (_encoder == 0)
if (!_encoder)
throw 1;
}
CEncoder::~CEncoder()
{
if (_encoder != 0)
if (_encoder)
Lzma2Enc_Destroy(_encoder);
}
HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props)
{
switch (propID)
@@ -42,12 +43,7 @@ HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzm
if (prop.vt == VT_UI4)
lzma2Props.blockSize = prop.ulVal;
else if (prop.vt == VT_UI8)
{
size_t v = (size_t)prop.uhVal.QuadPart;
if (v != prop.uhVal.QuadPart)
return E_INVALIDARG;
lzma2Props.blockSize = v;
}
lzma2Props.blockSize = prop.uhVal.QuadPart;
else
return E_INVALIDARG;
break;
@@ -60,6 +56,7 @@ HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzm
return S_OK;
}
STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
const PROPVARIANT *coderProps, UInt32 numProps)
{
@@ -73,30 +70,52 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
return SResToHRESULT(Lzma2Enc_SetProps(_encoder, &lzma2Props));
}
STDMETHODIMP CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs,
const PROPVARIANT *coderProps, UInt32 numProps)
{
for (UInt32 i = 0; i < numProps; i++)
{
const PROPVARIANT &prop = coderProps[i];
PROPID propID = propIDs[i];
if (propID == NCoderPropID::kExpectedDataSize)
if (prop.vt == VT_UI8)
Lzma2Enc_SetDataSize(_encoder, prop.uhVal.QuadPart);
}
return S_OK;
}
STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
{
Byte prop = Lzma2Enc_WriteProperties(_encoder);
return WriteStream(outStream, &prop, 1);
}
#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
{
CSeqInStreamWrap inWrap;
CSeqOutStreamWrap outWrap;
CCompressProgressWrap progressWrap;
inWrap.Init(inStream);
outWrap.Init(outStream);
progressWrap.Init(progress);
SRes res = Lzma2Enc_Encode(_encoder, &outWrap.vt, &inWrap.vt, progress ? &progressWrap.vt : NULL);
if (res == SZ_ERROR_READ && inWrap.Res != S_OK)
return inWrap.Res;
if (res == SZ_ERROR_WRITE && outWrap.Res != S_OK)
return outWrap.Res;
if (res == SZ_ERROR_PROGRESS && progressWrap.Res != S_OK)
return progressWrap.Res;
SRes res = Lzma2Enc_Encode2(_encoder,
&outWrap.vt, NULL, NULL,
&inWrap.vt, NULL, 0,
progress ? &progressWrap.vt : NULL);
RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ)
RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
return SResToHRESULT(res);
}

View File

@@ -16,16 +16,22 @@ class CEncoder:
public ICompressCoder,
public ICompressSetCoderProperties,
public ICompressWriteCoderProperties,
public ICompressSetCoderPropertiesOpt,
public CMyUnknownImp
{
CLzma2EncHandle _encoder;
public:
MY_UNKNOWN_IMP3(ICompressCoder, ICompressSetCoderProperties, ICompressWriteCoderProperties)
MY_UNKNOWN_IMP4(
ICompressCoder,
ICompressSetCoderProperties,
ICompressWriteCoderProperties,
ICompressSetCoderPropertiesOpt)
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
STDMETHOD(SetCoderPropertiesOpt)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
CEncoder();
virtual ~CEncoder();

View File

@@ -74,14 +74,19 @@ HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep)
return E_INVALIDARG;
return ParseMatchFinder(prop.bstrVal, &ep.btMode, &ep.numHashBytes) ? S_OK : E_INVALIDARG;
}
if (propID > NCoderPropID::kReduceSize)
return S_OK;
if (propID == NCoderPropID::kReduceSize)
{
if (prop.vt == VT_UI8)
ep.reduceSize = prop.uhVal.QuadPart;
else
return E_INVALIDARG;
return S_OK;
}
if (prop.vt != VT_UI4)
return E_INVALIDARG;
UInt32 v = prop.ulVal;
@@ -123,6 +128,22 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
return SResToHRESULT(LzmaEnc_SetProps(_encoder, &props));
}
STDMETHODIMP CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs,
const PROPVARIANT *coderProps, UInt32 numProps)
{
for (UInt32 i = 0; i < numProps; i++)
{
const PROPVARIANT &prop = coderProps[i];
PROPID propID = propIDs[i];
if (propID == NCoderPropID::kExpectedDataSize)
if (prop.vt == VT_UI8)
LzmaEnc_SetDataSize(_encoder, prop.uhVal.QuadPart);
}
return S_OK;
}
STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
{
Byte props[LZMA_PROPS_SIZE];
@@ -131,6 +152,10 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
return WriteStream(outStream, props, size);
}
#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
{
@@ -142,15 +167,15 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream
outWrap.Init(outStream);
progressWrap.Init(progress);
SRes res = LzmaEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt, progress ? &progressWrap.vt : NULL, &g_Alloc, &g_BigAlloc);
SRes res = LzmaEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt,
progress ? &progressWrap.vt : NULL, &g_Alloc, &g_BigAlloc);
_inputProcessed = inWrap.Processed;
if (res == SZ_ERROR_READ && inWrap.Res != S_OK)
return inWrap.Res;
if (res == SZ_ERROR_WRITE && outWrap.Res != S_OK)
return outWrap.Res;
if (res == SZ_ERROR_PROGRESS && progressWrap.Res != S_OK)
return progressWrap.Res;
RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ)
RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
return SResToHRESULT(res);
}

View File

@@ -16,17 +16,23 @@ class CEncoder:
public ICompressCoder,
public ICompressSetCoderProperties,
public ICompressWriteCoderProperties,
public ICompressSetCoderPropertiesOpt,
public CMyUnknownImp
{
CLzmaEncHandle _encoder;
UInt64 _inputProcessed;
public:
MY_UNKNOWN_IMP3(ICompressCoder, ICompressSetCoderProperties, ICompressWriteCoderProperties)
MY_UNKNOWN_IMP4(
ICompressCoder,
ICompressSetCoderProperties,
ICompressWriteCoderProperties,
ICompressSetCoderPropertiesOpt)
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
STDMETHOD(SetCoderPropertiesOpt)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
CEncoder();
virtual ~CEncoder();

View File

@@ -144,7 +144,8 @@ void CDecoder::ExecuteFilter(int tempFilterIndex, NVm::CBlockRef &outBlockRef)
CFilter *filter = _filters[tempFilter->FilterIndex];
if (!filter->IsSupported)
_unsupportedFilter = true;
_vm.Execute(filter, tempFilter, outBlockRef, filter->GlobalData);
if (!_vm.Execute(filter, tempFilter, outBlockRef, filter->GlobalData))
_unsupportedFilter = true;
delete tempFilter;
_tempFilters[tempFilterIndex] = 0;
}

View File

@@ -155,7 +155,7 @@ bool CVm::Execute(CProgram *prg, const CProgramInitState *initState,
#ifdef RARVM_STANDARD_FILTERS
if (prg->StandardFilterIndex >= 0)
ExecuteStandardFilter(prg->StandardFilterIndex);
res = ExecuteStandardFilter(prg->StandardFilterIndex);
else
#endif
{
@@ -880,10 +880,10 @@ static void E8E9Decode(Byte *data, UInt32 dataSize, UInt32 fileOffset, bool e9)
if (((*data++) & cmpMask) == 0xE8)
{
UInt32 offset = curPos + fileOffset;
UInt32 addr = (Int32)GetValue32(data);
UInt32 addr = GetValue32(data);
if (addr < kFileSize)
SetValue32(data, addr - offset);
else if ((Int32)addr < 0 && (Int32)(addr + offset) >= 0)
else if ((addr & 0x80000000) != 0 && ((addr + offset) & 0x80000000) == 0)
SetValue32(data, addr + kFileSize);
data += 4;
curPos += 4;
@@ -935,7 +935,7 @@ static void ItaniumDecode(Byte *data, UInt32 dataSize, UInt32 fileOffset)
static void DeltaDecode(Byte *data, UInt32 dataSize, UInt32 numChannels)
{
UInt32 srcPos = 0;
UInt32 border = dataSize * 2;
const UInt32 border = dataSize * 2;
for (UInt32 curChannel = 0; curChannel < numChannels; curChannel++)
{
Byte prevByte = 0;
@@ -947,12 +947,13 @@ static void DeltaDecode(Byte *data, UInt32 dataSize, UInt32 numChannels)
static void RgbDecode(Byte *srcData, UInt32 dataSize, UInt32 width, UInt32 posR)
{
Byte *destData = srcData + dataSize;
const UInt32 numChannels = 3;
for (UInt32 curChannel = 0; curChannel < numChannels; curChannel++)
const UInt32 kNumChannels = 3;
for (UInt32 curChannel = 0; curChannel < kNumChannels; curChannel++)
{
Byte prevByte = 0;
for (UInt32 i = curChannel; i < dataSize; i+= numChannels)
for (UInt32 i = curChannel; i < dataSize; i += kNumChannels)
{
unsigned int predicted;
if (i < width)
@@ -978,7 +979,8 @@ static void RgbDecode(Byte *srcData, UInt32 dataSize, UInt32 width, UInt32 posR)
}
if (dataSize < 3)
return;
for (UInt32 i = posR, border = dataSize - 2; i < border; i += 3)
const UInt32 border = dataSize - 2;
for (UInt32 i = posR; i < border; i += 3)
{
Byte g = destData[i + 1];
destData[i ] = (Byte)(destData[i ] + g);
@@ -1064,11 +1066,11 @@ static UInt32 UpCaseDecode(Byte *data, UInt32 dataSize)
}
*/
void CVm::ExecuteStandardFilter(unsigned filterIndex)
bool CVm::ExecuteStandardFilter(unsigned filterIndex)
{
UInt32 dataSize = R[4];
if (dataSize >= kGlobalOffset)
return;
return false;
EStandardFilter filterType = kStdFilters[filterIndex].Type;
switch (filterType)
@@ -1077,42 +1079,59 @@ void CVm::ExecuteStandardFilter(unsigned filterIndex)
case SF_E8E9:
E8E9Decode(Mem, dataSize, R[6], (filterType == SF_E8E9));
break;
case SF_ITANIUM:
ItaniumDecode(Mem, dataSize, R[6]);
break;
case SF_DELTA:
{
if (dataSize >= kGlobalOffset / 2)
break;
return false;
UInt32 numChannels = R[0];
if (numChannels == 0 || numChannels > 1024) // unrar 5.5.5
return false;
SetBlockPos(dataSize);
DeltaDecode(Mem, dataSize, R[0]);
DeltaDecode(Mem, dataSize, numChannels);
break;
}
case SF_RGB:
if (dataSize >= kGlobalOffset / 2)
break;
{
UInt32 width = R[0];
if (width <= 3)
break;
SetBlockPos(dataSize);
RgbDecode(Mem, dataSize, width, R[1]);
}
break;
case SF_AUDIO:
if (dataSize >= kGlobalOffset / 2)
break;
{
if (dataSize >= kGlobalOffset / 2 || dataSize < 3) // unrar 5.5.5
return false;
UInt32 width = R[0];
UInt32 posR = R[1];
if (width < 3 || width - 3 > dataSize || posR > 2) // unrar 5.5.5
return false;
SetBlockPos(dataSize);
AudioDecode(Mem, dataSize, R[0]);
RgbDecode(Mem, dataSize, width, posR);
break;
}
case SF_AUDIO:
{
if (dataSize >= kGlobalOffset / 2)
return false;
UInt32 numChannels = R[0];
if (numChannels == 0 || numChannels > 128) // unrar 5.5.5
return false;
SetBlockPos(dataSize);
AudioDecode(Mem, dataSize, numChannels);
break;
}
/*
case SF_UPCASE:
if (dataSize >= kGlobalOffset / 2)
break;
return false;
UInt32 destSize = UpCaseDecode(Mem, dataSize);
SetBlockSize(destSize);
SetBlockPos(dataSize);
break;
*/
}
return true;
}
#endif

View File

@@ -173,7 +173,7 @@ private:
#endif
#ifdef RARVM_STANDARD_FILTERS
void ExecuteStandardFilter(unsigned filterIndex);
bool ExecuteStandardFilter(unsigned filterIndex);
#endif
Byte *Mem;

View File

@@ -196,6 +196,8 @@ HRESULT CDecoder::ExecuteFilter(const CFilter &f)
default:
_unsupportedFilter = true;
memset(_filterSrc, 0, f.Size);
// return S_OK; // unrar
}
return WriteData(useDest ?
@@ -301,7 +303,11 @@ HRESULT CDecoder::AddFilter(CBitDecoder &_bitStream)
UInt32 blockStart = ReadUInt32(_bitStream);
f.Size = ReadUInt32(_bitStream);
// if (f.Size > ((UInt32)1 << 16)) _unsupportedFilter = true;
if (f.Size > ((UInt32)1 << 22))
{
_unsupportedFilter = true;
f.Size = 0; // unrar 5.5.5
}
f.Type = (Byte)_bitStream.ReadBits9fix(3);
f.Channels = 0;

View File

@@ -16,6 +16,19 @@ namespace NCompress {
namespace NXz {
CXzUnpackerCPP::CXzUnpackerCPP(): InBuf(NULL), OutBuf(NULL)
{
XzUnpacker_Construct(&p, &g_Alloc);
}
CXzUnpackerCPP::~CXzUnpackerCPP()
{
XzUnpacker_Free(&p);
MidFree(InBuf);
MidFree(OutBuf);
}
void CStatInfo::Clear()
{
InSize = 0;
@@ -40,20 +53,6 @@ void CStatInfo::Clear()
}
CXzUnpackerCPP::CXzUnpackerCPP(): InBuf(0), OutBuf(0)
{
XzUnpacker_Construct(&p, &g_Alloc);
}
CXzUnpackerCPP::~CXzUnpackerCPP()
{
XzUnpacker_Free(&p);
MidFree(InBuf);
MidFree(OutBuf);
}
HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream,
const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *progress)
{
@@ -95,8 +94,12 @@ HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream
SizeT inLen = inSize - inPos;
SizeT outLen = kOutBufSize - outPos;
ECoderFinishMode finishMode = CODER_FINISH_ANY;
/*
// 17.01 : the code was disabled:
if (inSize == 0)
finishMode = CODER_FINISH_END;
*/
if (outSizeLimit)
{

View File

@@ -3,13 +3,11 @@
#ifndef __XZ_DECODER_H
#define __XZ_DECODER_H
#include "../../Common/MyCom.h"
#include "../ICoder.h"
#include "../../../C/Xz.h"
#include "../../Common/MyCom.h"
// #include "../../Archive/XzHandler.h"
#include "../ICoder.h"
namespace NCompress {
namespace NXz {

View File

@@ -4,6 +4,9 @@
#include "../../../C/Alloc.h"
#include "../../Common/MyString.h"
#include "../../Common/StringToInt.h"
#include "../Common/CWrappers.h"
#include "../Common/StreamUtils.h"
@@ -19,172 +22,224 @@ HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzm
namespace NXz {
extern "C" {
static void *SzBigAlloc(ISzAllocPtr, size_t size) { return BigAlloc(size); }
static void SzBigFree(ISzAllocPtr, void *address) { BigFree(address); }
static const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
static void *SzAlloc(ISzAllocPtr, size_t size) { return MyAlloc(size); }
static void SzFree(ISzAllocPtr, void *address) { MyFree(address); }
static const ISzAlloc g_Alloc = { SzAlloc, SzFree };
}
void CEncoder::InitCoderProps()
{
Lzma2EncProps_Init(&_lzma2Props);
XzProps_Init(&xzProps);
XzFilterProps_Init(&filter);
xzProps.lzma2Props = &_lzma2Props;
// xzProps.filterProps = (_filterId != 0 ? &filter : NULL);
xzProps.filterProps = NULL;
}
CEncoder::CEncoder()
{
InitCoderProps();
XzProps_Init(&xzProps);
_encoder = NULL;
_encoder = XzEnc_Create(&g_Alloc, &g_BigAlloc);
if (!_encoder)
throw 1;
}
CEncoder::~CEncoder()
{
if (_encoder)
XzEnc_Destroy(_encoder);
}
struct CMethodNamePair
{
UInt32 Id;
const char *Name;
};
static const CMethodNamePair g_NamePairs[] =
{
{ XZ_ID_Delta, "Delta" },
{ XZ_ID_X86, "BCJ" },
{ XZ_ID_PPC, "PPC" },
{ XZ_ID_IA64, "IA64" },
{ XZ_ID_ARM, "ARM" },
{ XZ_ID_ARMT, "ARMT" },
{ XZ_ID_SPARC, "SPARC" }
// { XZ_ID_LZMA2, "LZMA2" }
};
static int FilterIdFromName(const wchar_t *name)
{
for (unsigned i = 0; i < ARRAY_SIZE(g_NamePairs); i++)
{
const CMethodNamePair &pair = g_NamePairs[i];
if (StringsAreEqualNoCase_Ascii(name, pair.Name))
return (int)pair.Id;
}
return -1;
}
HRESULT CEncoder::SetCheckSize(UInt32 checkSizeInBytes)
{
unsigned id;
switch (checkSizeInBytes)
{
case 0: id = XZ_CHECK_NO; break;
case 4: id = XZ_CHECK_CRC32; break;
case 8: id = XZ_CHECK_CRC64; break;
case 32: id = XZ_CHECK_SHA256; break;
default: return E_INVALIDARG;
}
xzProps.checkId = id;
return S_OK;
}
HRESULT CEncoder::SetCoderProp(PROPID propID, const PROPVARIANT &prop)
{
return NLzma2::SetLzma2Prop(propID, prop, _lzma2Props);
if (propID == NCoderPropID::kNumThreads)
{
if (prop.vt != VT_UI4)
return E_INVALIDARG;
xzProps.numTotalThreads = (int)(prop.ulVal);
return S_OK;
}
if (propID == NCoderPropID::kCheckSize)
{
if (prop.vt != VT_UI4)
return E_INVALIDARG;
return SetCheckSize(prop.ulVal);
}
if (propID == NCoderPropID::kBlockSize2)
{
if (prop.vt == VT_UI4)
xzProps.blockSize = prop.ulVal;
else if (prop.vt == VT_UI8)
xzProps.blockSize = prop.uhVal.QuadPart;
else
return E_INVALIDARG;
return S_OK;
}
if (propID == NCoderPropID::kReduceSize)
{
if (prop.vt == VT_UI8)
xzProps.reduceSize = prop.uhVal.QuadPart;
else
return E_INVALIDARG;
return S_OK;
}
if (propID == NCoderPropID::kFilter)
{
if (prop.vt == VT_UI4)
{
UInt32 id32 = prop.ulVal;
if (id32 == XZ_ID_Delta)
return E_INVALIDARG;
xzProps.filterProps.id = prop.ulVal;
}
else
{
if (prop.vt != VT_BSTR)
return E_INVALIDARG;
const wchar_t *name = prop.bstrVal;
const wchar_t *end;
UInt32 id32 = ConvertStringToUInt32(name, &end);
if (end != name)
name = end;
else
{
if (IsString1PrefixedByString2_NoCase_Ascii(name, "Delta"))
{
name += 5; // strlen("Delta");
id32 = XZ_ID_Delta;
}
else
{
int filterId = FilterIdFromName(prop.bstrVal);
if (filterId < 0 /* || filterId == XZ_ID_LZMA2 */)
return E_INVALIDARG;
id32 = filterId;
}
}
if (id32 == XZ_ID_Delta)
{
wchar_t c = *name;
if (c != '-' && c != ':')
return E_INVALIDARG;
name++;
UInt32 delta = ConvertStringToUInt32(name, &end);
if (end == name || *end != 0 || delta == 0 || delta > 256)
return E_INVALIDARG;
xzProps.filterProps.delta = delta;
}
xzProps.filterProps.id = id32;
}
return S_OK;
}
return NLzma2::SetLzma2Prop(propID, prop, xzProps.lzma2Props);
}
STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
const PROPVARIANT *coderProps, UInt32 numProps)
{
Lzma2EncProps_Init(&_lzma2Props);
XzProps_Init(&xzProps);
for (UInt32 i = 0; i < numProps; i++)
{
RINOK(SetCoderProp(propIDs[i], coderProps[i]));
}
return S_OK;
// return SResToHRESULT(Lzma2Enc_SetProps(_encoder, &lzma2Props));
// return SResToHRESULT(XzEnc_SetProps(_encoder, &xzProps));
}
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 * /* outSize */,
ICompressProgressInfo *progress)
STDMETHODIMP CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs,
const PROPVARIANT *coderProps, UInt32 numProps)
{
CSeqOutStreamWrap seqOutStream;
seqOutStream.Init(outStream);
// if (IntToBool(newData))
for (UInt32 i = 0; i < numProps; i++)
{
/*
UInt64 size;
{
NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(0, kpidSize, &prop));
if (prop.vt != VT_UI8)
return E_INVALIDARG;
size = prop.uhVal.QuadPart;
RINOK(updateCallback->SetTotal(size));
}
*/
/*
CLzma2EncProps lzma2Props;
Lzma2EncProps_Init(&lzma2Props);
lzma2Props.lzmaProps.level = GetLevel();
*/
CSeqInStreamWrap seqInStream;
seqInStream.Init(inStream);
/*
{
NCOM::CPropVariant prop = (UInt64)size;
RINOK(NCompress::NLzma2::SetLzma2Prop(NCoderPropID::kReduceSize, prop, lzma2Props));
}
FOR_VECTOR (i, _methods)
{
COneMethodInfo &m = _methods[i];
SetGlobalLevelAndThreads(m
#ifndef _7ZIP_ST
, _numThreads
#endif
);
{
FOR_VECTOR (j, m.Props)
{
const CProp &prop = m.Props[j];
RINOK(NCompress::NLzma2::SetLzma2Prop(prop.Id, prop.Value, lzma2Props));
}
}
}
#ifndef _7ZIP_ST
lzma2Props.numTotalThreads = _numThreads;
#endif
*/
CCompressProgressWrap progressWrap;
progressWrap.Init(progress);
xzProps.checkId = XZ_CHECK_CRC32;
// xzProps.checkId = XZ_CHECK_CRC64;
/*
CXzProps xzProps;
CXzFilterProps filter;
XzProps_Init(&xzProps);
XzFilterProps_Init(&filter);
xzProps.lzma2Props = &_lzma2Props;
*/
/*
xzProps.filterProps = (_filterId != 0 ? &filter : NULL);
switch (_crcSize)
{
case 0: xzProps.checkId = XZ_CHECK_NO; break;
case 4: xzProps.checkId = XZ_CHECK_CRC32; break;
case 8: xzProps.checkId = XZ_CHECK_CRC64; break;
case 32: xzProps.checkId = XZ_CHECK_SHA256; break;
default: return E_INVALIDARG;
}
filter.id = _filterId;
if (_filterId == XZ_ID_Delta)
{
bool deltaDefined = false;
FOR_VECTOR (j, _filterMethod.Props)
{
const CProp &prop = _filterMethod.Props[j];
if (prop.Id == NCoderPropID::kDefaultProp && prop.Value.vt == VT_UI4)
{
UInt32 delta = (UInt32)prop.Value.ulVal;
if (delta < 1 || delta > 256)
return E_INVALIDARG;
filter.delta = delta;
deltaDefined = true;
}
}
if (!deltaDefined)
return E_INVALIDARG;
}
*/
SRes res = Xz_Encode(&seqOutStream.vt, &seqInStream.vt, &xzProps, progress ? &progressWrap.vt : NULL);
/*
if (res == SZ_OK)
return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
*/
return SResToHRESULT(res);
const PROPVARIANT &prop = coderProps[i];
PROPID propID = propIDs[i];
if (propID == NCoderPropID::kExpectedDataSize)
if (prop.vt == VT_UI8)
XzEnc_SetDataSize(_encoder, prop.uhVal.QuadPart);
}
return S_OK;
}
#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
{
CSeqInStreamWrap inWrap;
CSeqOutStreamWrap outWrap;
CCompressProgressWrap progressWrap;
inWrap.Init(inStream);
outWrap.Init(outStream);
progressWrap.Init(progress);
SRes res = XzEnc_SetProps(_encoder, &xzProps);
if (res == SZ_OK)
res = XzEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt, progress ? &progressWrap.vt : NULL);
// SRes res = Xz_Encode(&outWrap.vt, &inWrap.vt, &xzProps, progress ? &progressWrap.vt : NULL);
RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ)
RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
return SResToHRESULT(res);
}
}}

View File

@@ -16,24 +16,26 @@ namespace NXz {
class CEncoder:
public ICompressCoder,
public ICompressSetCoderProperties,
public ICompressSetCoderPropertiesOpt,
public CMyUnknownImp
{
// CXzEncHandle _encoder;
CXzEncHandle _encoder;
public:
CLzma2EncProps _lzma2Props;
CXzProps xzProps;
CXzFilterProps filter;
MY_UNKNOWN_IMP2(ICompressCoder, ICompressSetCoderProperties)
MY_UNKNOWN_IMP3(
ICompressCoder,
ICompressSetCoderProperties,
ICompressSetCoderPropertiesOpt)
void InitCoderProps();
HRESULT SetCheckSize(UInt32 checkSizeInBytes);
HRESULT SetCoderProp(PROPID propID, const PROPVARIANT &prop);
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
STDMETHOD(SetCoderPropertiesOpt)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
CEncoder();
virtual ~CEncoder();