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 12 namespace NCompress { 13 14 namespace NLzma { 15 16 HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep); 17 18 } 19 20 namespace NLzma2 { 21 22 CEncoder::CEncoder() 23 { 24 _encoder = 0; 25 _encoder = Lzma2Enc_Create(&g_Alloc, &g_BigAlloc); 26 if (_encoder == 0) 27 throw 1; 28 } 29 30 CEncoder::~CEncoder() 31 { 32 if (_encoder != 0) 33 Lzma2Enc_Destroy(_encoder); 34 } 35 36 HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props) 37 { 38 switch (propID) 39 { 40 case NCoderPropID::kBlockSize: 41 { 42 if (prop.vt == VT_UI4) 43 lzma2Props.blockSize = prop.ulVal; 44 else if (prop.vt == VT_UI8) 45 { 46 size_t v = (size_t)prop.uhVal.QuadPart; 47 if (v != prop.uhVal.QuadPart) 48 return E_INVALIDARG; 49 lzma2Props.blockSize = v; 50 } 51 else 52 return E_INVALIDARG; 53 break; 54 } 55 case NCoderPropID::kNumThreads: 56 if (prop.vt != VT_UI4) return E_INVALIDARG; lzma2Props.numTotalThreads = (int)(prop.ulVal); break; 57 default: 58 RINOK(NLzma::SetLzmaProp(propID, prop, lzma2Props.lzmaProps)); 59 } 60 return S_OK; 61 } 62 63 STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, 64 const PROPVARIANT *coderProps, UInt32 numProps) 65 { 66 CLzma2EncProps lzma2Props; 67 Lzma2EncProps_Init(&lzma2Props); 68 69 for (UInt32 i = 0; i < numProps; i++) 70 { 71 RINOK(SetLzma2Prop(propIDs[i], coderProps[i], lzma2Props)); 72 } 73 return SResToHRESULT(Lzma2Enc_SetProps(_encoder, &lzma2Props)); 74 } 75 76 STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) 77 { 78 Byte prop = Lzma2Enc_WriteProperties(_encoder); 79 return WriteStream(outStream, &prop, 1); 80 } 81 82 STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, 83 const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) 84 { 85 CSeqInStreamWrap inWrap(inStream); 86 CSeqOutStreamWrap outWrap(outStream); 87 CCompressProgressWrap progressWrap(progress); 88 89 SRes res = Lzma2Enc_Encode(_encoder, &outWrap.p, &inWrap.p, progress ? &progressWrap.p : NULL); 90 if (res == SZ_ERROR_READ && inWrap.Res != S_OK) 91 return inWrap.Res; 92 if (res == SZ_ERROR_WRITE && outWrap.Res != S_OK) 93 return outWrap.Res; 94 if (res == SZ_ERROR_PROGRESS && progressWrap.Res != S_OK) 95 return progressWrap.Res; 96 return SResToHRESULT(res); 97 } 98 99 }} 100