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 = 0;
25 _encoder = Lzma2Enc_Create(&g_Alloc, &g_BigAlloc);
26 if (_encoder == 0)
27 throw 1;
28 }
29
~CEncoder()30 CEncoder::~CEncoder()
31 {
32 if (_encoder != 0)
33 Lzma2Enc_Destroy(_encoder);
34 }
35
SetLzma2Prop(PROPID propID,const PROPVARIANT & prop,CLzma2EncProps & lzma2Props)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
SetCoderProperties(const PROPID * propIDs,const PROPVARIANT * coderProps,UInt32 numProps)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
WriteCoderProperties(ISequentialOutStream * outStream)76 STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
77 {
78 Byte prop = Lzma2Enc_WriteProperties(_encoder);
79 return WriteStream(outStream, &prop, 1);
80 }
81
Code(ISequentialInStream * inStream,ISequentialOutStream * outStream,const UInt64 *,const UInt64 *,ICompressProgressInfo * progress)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