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