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
CEncoder()22 CEncoder::CEncoder()
23 {
24 _encoder = NULL;
25 _encoder = Lzma2Enc_Create(&g_AlignedAlloc, &g_BigAlloc);
26 if (!_encoder)
27 throw 1;
28 }
29
~CEncoder()30 CEncoder::~CEncoder()
31 {
32 if (_encoder)
33 Lzma2Enc_Destroy(_encoder);
34 }
35
36
SetLzma2Prop(PROPID propID,const PROPVARIANT & prop,CLzma2EncProps & lzma2Props)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
SetCoderProperties(const PROPID * propIDs,const PROPVARIANT * coderProps,UInt32 numProps)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
SetCoderPropertiesOpt(const PROPID * propIDs,const PROPVARIANT * coderProps,UInt32 numProps)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
WriteCoderProperties(ISequentialOutStream * outStream)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
Code(ISequentialInStream * inStream,ISequentialOutStream * outStream,const UInt64 *,const UInt64 *,ICompressProgressInfo * progress)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 }}
123