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