1// Lzma2Encoder.cpp 2 3#include "StdAfx.h" 4 5#include "../../../C/Alloc.h" 6 7#include "../Common/CWrappers.h" 8#include "../Common/StreamUtils.h" 9 10#include "Lzma2Encoder.h" 11 12namespace NCompress { 13 14namespace NLzma { 15 16HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep); 17 18} 19 20namespace NLzma2 { 21 22static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); } 23static void SzBigFree(void *, void *address) { BigFree(address); } 24static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; 25 26static void *SzAlloc(void *, size_t size) { return MyAlloc(size); } 27static void SzFree(void *, void *address) { MyFree(address); } 28static ISzAlloc g_Alloc = { SzAlloc, SzFree }; 29 30CEncoder::CEncoder() 31{ 32 _encoder = 0; 33 _encoder = Lzma2Enc_Create(&g_Alloc, &g_BigAlloc); 34 if (_encoder == 0) 35 throw 1; 36} 37 38CEncoder::~CEncoder() 39{ 40 if (_encoder != 0) 41 Lzma2Enc_Destroy(_encoder); 42} 43 44HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props) 45{ 46 switch (propID) 47 { 48 case NCoderPropID::kBlockSize: 49 if (prop.vt != VT_UI4) return E_INVALIDARG; lzma2Props.blockSize = prop.ulVal; break; 50 case NCoderPropID::kNumThreads: 51 if (prop.vt != VT_UI4) return E_INVALIDARG; lzma2Props.numTotalThreads = (int)(prop.ulVal); break; 52 default: 53 RINOK(NLzma::SetLzmaProp(propID, prop, lzma2Props.lzmaProps)); 54 } 55 return S_OK; 56} 57 58STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, 59 const PROPVARIANT *coderProps, UInt32 numProps) 60{ 61 CLzma2EncProps lzma2Props; 62 Lzma2EncProps_Init(&lzma2Props); 63 64 for (UInt32 i = 0; i < numProps; i++) 65 { 66 RINOK(SetLzma2Prop(propIDs[i], coderProps[i], lzma2Props)); 67 } 68 return SResToHRESULT(Lzma2Enc_SetProps(_encoder, &lzma2Props)); 69} 70 71STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) 72{ 73 Byte prop = Lzma2Enc_WriteProperties(_encoder); 74 return WriteStream(outStream, &prop, 1); 75} 76 77STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, 78 const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) 79{ 80 CSeqInStreamWrap inWrap(inStream); 81 CSeqOutStreamWrap outWrap(outStream); 82 CCompressProgressWrap progressWrap(progress); 83 84 SRes res = Lzma2Enc_Encode(_encoder, &outWrap.p, &inWrap.p, progress ? &progressWrap.p : NULL); 85 if (res == SZ_ERROR_READ && inWrap.Res != S_OK) 86 return inWrap.Res; 87 if (res == SZ_ERROR_WRITE && outWrap.Res != S_OK) 88 return outWrap.Res; 89 if (res == SZ_ERROR_PROGRESS && progressWrap.Res != S_OK) 90 return progressWrap.Res; 91 return SResToHRESULT(res); 92} 93 94}} 95