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