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
SzBigAlloc(void *,size_t size)22 static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); }
SzBigFree(void *,void * address)23 static void SzBigFree(void *, void *address) { BigFree(address); }
24 static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
25
SzAlloc(void *,size_t size)26 static void *SzAlloc(void *, size_t size) { return MyAlloc(size); }
SzFree(void *,void * address)27 static void SzFree(void *, void *address) { MyFree(address); }
28 static ISzAlloc g_Alloc = { SzAlloc, SzFree };
29
CEncoder()30 CEncoder::CEncoder()
31 {
32 _encoder = 0;
33 _encoder = Lzma2Enc_Create(&g_Alloc, &g_BigAlloc);
34 if (_encoder == 0)
35 throw 1;
36 }
37
~CEncoder()38 CEncoder::~CEncoder()
39 {
40 if (_encoder != 0)
41 Lzma2Enc_Destroy(_encoder);
42 }
43
SetLzma2Prop(PROPID propID,const PROPVARIANT & prop,CLzma2EncProps & lzma2Props)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
SetCoderProperties(const PROPID * propIDs,const PROPVARIANT * coderProps,UInt32 numProps)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
WriteCoderProperties(ISequentialOutStream * outStream)71 STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
72 {
73 Byte prop = Lzma2Enc_WriteProperties(_encoder);
74 return WriteStream(outStream, &prop, 1);
75 }
76
Code(ISequentialInStream * inStream,ISequentialOutStream * outStream,const UInt64 *,const UInt64 *,ICompressProgressInfo * progress)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