blob: 0dc7e23b46313ae111150eab87f1db2ad0f99324 [file] [log] [blame]
// 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);
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;
}
Z7_COM7F_IMF(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));
}
Z7_COM7F_IMF(CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs,
const PROPVARIANT *coderProps, UInt32 numProps))
{
for (UInt32 i = 0; i < numProps; i++)
{
const PROPVARIANT &prop = coderProps[i];
const PROPID propID = propIDs[i];
if (propID == NCoderPropID::kExpectedDataSize)
if (prop.vt == VT_UI8)
Lzma2Enc_SetDataSize(_encoder, prop.uhVal.QuadPart);
}
return S_OK;
}
Z7_COM7F_IMF(CEncoder::WriteCoderProperties(ISequentialOutStream *outStream))
{
const 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;
Z7_COM7F_IMF(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);
}
}}