// Lzma2Encoder.cpp #include "StdAfx.h" #include "../../../C/Alloc.h" #include "../Common/CWrappers.h" #include "../Common/StreamUtils.h" #include "Lzma2Encoder.h" namespace NCompress { namespace NLzma { HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep); } namespace NLzma2 { CEncoder::CEncoder() { _encoder = NULL; _encoder = Lzma2Enc_Create(&g_AlignedAlloc, &g_BigAlloc); if (!_encoder) throw 1; } CEncoder::~CEncoder() { if (_encoder) Lzma2Enc_Destroy(_encoder); } HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props) { switch (propID) { case NCoderPropID::kBlockSize: { if (prop.vt == VT_UI4) lzma2Props.blockSize = prop.ulVal; else if (prop.vt == VT_UI8) lzma2Props.blockSize = prop.uhVal.QuadPart; else return E_INVALIDARG; break; } case NCoderPropID::kNumThreads: if (prop.vt != VT_UI4) return E_INVALIDARG; lzma2Props.numTotalThreads = (int)(prop.ulVal); break; default: RINOK(NLzma::SetLzmaProp(propID, prop, lzma2Props.lzmaProps)); } return S_OK; } STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps) { CLzma2EncProps lzma2Props; Lzma2EncProps_Init(&lzma2Props); for (UInt32 i = 0; i < numProps; i++) { RINOK(SetLzma2Prop(propIDs[i], coderProps[i], lzma2Props)); } return SResToHRESULT(Lzma2Enc_SetProps(_encoder, &lzma2Props)); } STDMETHODIMP CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps) { for (UInt32 i = 0; i < numProps; i++) { const PROPVARIANT &prop = coderProps[i]; PROPID propID = propIDs[i]; if (propID == NCoderPropID::kExpectedDataSize) if (prop.vt == VT_UI8) Lzma2Enc_SetDataSize(_encoder, prop.uhVal.QuadPart); } return S_OK; } STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) { Byte prop = Lzma2Enc_WriteProperties(_encoder); return WriteStream(outStream, &prop, 1); } #define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \ if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes; STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) { CSeqInStreamWrap inWrap; CSeqOutStreamWrap outWrap; CCompressProgressWrap progressWrap; inWrap.Init(inStream); outWrap.Init(outStream); progressWrap.Init(progress); SRes res = Lzma2Enc_Encode2(_encoder, &outWrap.vt, NULL, NULL, &inWrap.vt, NULL, 0, progress ? &progressWrap.vt : NULL); RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ) RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE) RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS) return SResToHRESULT(res); } }}