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 static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); } 23 static void SzBigFree(void *, void *address) { BigFree(address); } 24 static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; 25 26 static void *SzAlloc(void *, size_t size) { return MyAlloc(size); } 27 static void SzFree(void *, void *address) { MyFree(address); } 28 static ISzAlloc g_Alloc = { SzAlloc, SzFree }; 29 30 CEncoder::CEncoder() 31 { 32 _encoder = 0; 33 _encoder = Lzma2Enc_Create(&g_Alloc, &g_BigAlloc); 34 if (_encoder == 0) 35 throw 1; 36 } 37 38 CEncoder::~CEncoder() 39 { 40 if (_encoder != 0) 41 Lzma2Enc_Destroy(_encoder); 42 } 43 44 HRESULT 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 58 STDMETHODIMP 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 71 STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) 72 { 73 Byte prop = Lzma2Enc_WriteProperties(_encoder); 74 return WriteStream(outStream, &prop, 1); 75 } 76 77 STDMETHODIMP 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