Lzma2Encoder.cpp (3079B)
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 = NULL; 25 _encoder = Lzma2Enc_Create(&g_AlignedAlloc, &g_BigAlloc); 26 if (!_encoder) 27 throw 1; 28 } 29 30 CEncoder::~CEncoder() 31 { 32 if (_encoder) 33 Lzma2Enc_Destroy(_encoder); 34 } 35 36 37 HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props) 38 { 39 switch (propID) 40 { 41 case NCoderPropID::kBlockSize: 42 { 43 if (prop.vt == VT_UI4) 44 lzma2Props.blockSize = prop.ulVal; 45 else if (prop.vt == VT_UI8) 46 lzma2Props.blockSize = prop.uhVal.QuadPart; 47 else 48 return E_INVALIDARG; 49 break; 50 } 51 case NCoderPropID::kNumThreads: 52 if (prop.vt != VT_UI4) return E_INVALIDARG; lzma2Props.numTotalThreads = (int)(prop.ulVal); break; 53 default: 54 RINOK(NLzma::SetLzmaProp(propID, prop, lzma2Props.lzmaProps)); 55 } 56 return S_OK; 57 } 58 59 60 STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, 61 const PROPVARIANT *coderProps, UInt32 numProps) 62 { 63 CLzma2EncProps lzma2Props; 64 Lzma2EncProps_Init(&lzma2Props); 65 66 for (UInt32 i = 0; i < numProps; i++) 67 { 68 RINOK(SetLzma2Prop(propIDs[i], coderProps[i], lzma2Props)); 69 } 70 return SResToHRESULT(Lzma2Enc_SetProps(_encoder, &lzma2Props)); 71 } 72 73 74 STDMETHODIMP CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs, 75 const PROPVARIANT *coderProps, UInt32 numProps) 76 { 77 for (UInt32 i = 0; i < numProps; i++) 78 { 79 const PROPVARIANT &prop = coderProps[i]; 80 PROPID propID = propIDs[i]; 81 if (propID == NCoderPropID::kExpectedDataSize) 82 if (prop.vt == VT_UI8) 83 Lzma2Enc_SetDataSize(_encoder, prop.uhVal.QuadPart); 84 } 85 return S_OK; 86 } 87 88 89 STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) 90 { 91 Byte prop = Lzma2Enc_WriteProperties(_encoder); 92 return WriteStream(outStream, &prop, 1); 93 } 94 95 96 #define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \ 97 if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes; 98 99 STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, 100 const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) 101 { 102 CSeqInStreamWrap inWrap; 103 CSeqOutStreamWrap outWrap; 104 CCompressProgressWrap progressWrap; 105 106 inWrap.Init(inStream); 107 outWrap.Init(outStream); 108 progressWrap.Init(progress); 109 110 SRes res = Lzma2Enc_Encode2(_encoder, 111 &outWrap.vt, NULL, NULL, 112 &inWrap.vt, NULL, 0, 113 progress ? &progressWrap.vt : NULL); 114 115 RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ) 116 RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE) 117 RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS) 118 119 return SResToHRESULT(res); 120 } 121 122 }}